|
@@ -1,9 +1,9 @@
|
|
|
package logic
|
|
|
|
|
|
import (
|
|
|
+ "context"
|
|
|
"errors"
|
|
|
"fmt"
|
|
|
- "log"
|
|
|
"net"
|
|
|
"net/netip"
|
|
|
|
|
@@ -16,8 +16,15 @@ import (
|
|
|
"golang.zx2c4.com/wireguard/wgctrl/wgtypes"
|
|
|
)
|
|
|
|
|
|
+var (
|
|
|
+ // PeerUpdateCtx context to send to host peer updates
|
|
|
+ PeerUpdateCtx context.Context
|
|
|
+ // PeerUpdateStop - the cancel for PeerUpdateCtx
|
|
|
+ PeerUpdateStop context.CancelFunc
|
|
|
+)
|
|
|
+
|
|
|
// GetProxyUpdateForHost - gets the proxy update for host
|
|
|
-func GetProxyUpdateForHost(host *models.Host) (models.ProxyManagerPayload, error) {
|
|
|
+func GetProxyUpdateForHost(ctx context.Context, host *models.Host) (models.ProxyManagerPayload, error) {
|
|
|
proxyPayload := models.ProxyManagerPayload{
|
|
|
Action: models.ProxyUpdate,
|
|
|
}
|
|
@@ -34,14 +41,13 @@ func GetProxyUpdateForHost(host *models.Host) (models.ProxyManagerPayload, error
|
|
|
} else {
|
|
|
logger.Log(0, "couldn't find relay host for: ", host.ID.String())
|
|
|
}
|
|
|
-
|
|
|
}
|
|
|
if host.IsRelay {
|
|
|
relayedHosts := GetRelayedHosts(host)
|
|
|
relayPeersMap := make(map[string]models.RelayedConf)
|
|
|
for _, relayedHost := range relayedHosts {
|
|
|
relayedHost := relayedHost
|
|
|
- payload, err := GetPeerUpdateForHost("", &relayedHost, nil)
|
|
|
+ payload, err := GetPeerUpdateForHost(ctx, "", &relayedHost, nil, nil)
|
|
|
if err == nil {
|
|
|
relayedEndpoint, udpErr := net.ResolveUDPAddr("udp", fmt.Sprintf("%s:%d", relayedHost.EndpointIP, GetPeerListenPort(&relayedHost)))
|
|
|
if udpErr == nil {
|
|
@@ -65,6 +71,9 @@ func GetProxyUpdateForHost(host *models.Host) (models.ProxyManagerPayload, error
|
|
|
if err != nil {
|
|
|
continue
|
|
|
}
|
|
|
+ if !node.Connected || node.PendingDelete || node.Action == models.NODE_DELETE {
|
|
|
+ continue
|
|
|
+ }
|
|
|
currentPeers, err := GetNetworkNodes(node.Network)
|
|
|
if err != nil {
|
|
|
continue
|
|
@@ -74,6 +83,9 @@ func GetProxyUpdateForHost(host *models.Host) (models.ProxyManagerPayload, error
|
|
|
//skip yourself
|
|
|
continue
|
|
|
}
|
|
|
+ if !peer.Connected || peer.PendingDelete || peer.Action == models.NODE_DELETE {
|
|
|
+ continue
|
|
|
+ }
|
|
|
peerHost, err := GetHost(peer.HostID.String())
|
|
|
if err != nil {
|
|
|
continue
|
|
@@ -84,6 +96,7 @@ func GetProxyUpdateForHost(host *models.Host) (models.ProxyManagerPayload, error
|
|
|
currPeerConf = models.PeerConf{
|
|
|
Proxy: peerHost.ProxyEnabled,
|
|
|
PublicListenPort: int32(GetPeerListenPort(peerHost)),
|
|
|
+ ProxyListenPort: GetProxyListenPort(peerHost),
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -117,11 +130,24 @@ func GetProxyUpdateForHost(host *models.Host) (models.ProxyManagerPayload, error
|
|
|
return proxyPayload, nil
|
|
|
}
|
|
|
|
|
|
+// ResetPeerUpdateContext - kills any current peer updates and resets the context
|
|
|
+func ResetPeerUpdateContext() {
|
|
|
+ if PeerUpdateCtx != nil && PeerUpdateStop != nil {
|
|
|
+ PeerUpdateStop() // tell any current peer updates to stop
|
|
|
+ }
|
|
|
+
|
|
|
+ PeerUpdateCtx, PeerUpdateStop = context.WithCancel(context.Background())
|
|
|
+}
|
|
|
+
|
|
|
// GetPeerUpdateForHost - gets the consolidated peer update for the host from all networks
|
|
|
-func GetPeerUpdateForHost(network string, host *models.Host, deletedNode *models.Node) (models.HostPeerUpdate, error) {
|
|
|
+func GetPeerUpdateForHost(ctx context.Context, network string, host *models.Host, deletedNode *models.Node, deletedClient *models.ExtClient) (models.HostPeerUpdate, error) {
|
|
|
if host == nil {
|
|
|
return models.HostPeerUpdate{}, errors.New("host is nil")
|
|
|
}
|
|
|
+ allNodes, err := GetAllNodes()
|
|
|
+ if err != nil {
|
|
|
+ return models.HostPeerUpdate{}, err
|
|
|
+ }
|
|
|
// track which nodes are deleted
|
|
|
// after peer calculation, if peer not in list, add delete config of peer
|
|
|
hostPeerUpdate := models.HostPeerUpdate{
|
|
@@ -133,18 +159,17 @@ func GetPeerUpdateForHost(network string, host *models.Host, deletedNode *models
|
|
|
IngressInfo: models.IngressInfo{
|
|
|
ExtPeers: make(map[string]models.ExtClientInfo),
|
|
|
},
|
|
|
- EgressInfo: make(map[string]models.EgressInfo),
|
|
|
- PeerIDs: make(models.PeerMap, 0),
|
|
|
- Peers: []wgtypes.PeerConfig{},
|
|
|
- NodePeers: []wgtypes.PeerConfig{},
|
|
|
+ EgressInfo: make(map[string]models.EgressInfo),
|
|
|
+ PeerIDs: make(models.PeerMap, 0),
|
|
|
+ Peers: []wgtypes.PeerConfig{},
|
|
|
+ NodePeers: []wgtypes.PeerConfig{},
|
|
|
+ HostNetworkInfo: models.HostInfoMap{},
|
|
|
}
|
|
|
- var deletedNodes = []models.Node{} // used to track deleted nodes
|
|
|
- if deletedNode != nil {
|
|
|
- deletedNodes = append(deletedNodes, *deletedNode)
|
|
|
- }
|
|
|
- logger.Log(1, "peer update for host ", host.ID.String())
|
|
|
+
|
|
|
+ logger.Log(1, "peer update for host", host.ID.String())
|
|
|
peerIndexMap := make(map[string]int)
|
|
|
for _, nodeID := range host.Nodes {
|
|
|
+ nodeID := nodeID
|
|
|
node, err := GetNodeByID(nodeID)
|
|
|
if err != nil {
|
|
|
continue
|
|
@@ -152,230 +177,246 @@ func GetPeerUpdateForHost(network string, host *models.Host, deletedNode *models
|
|
|
if !node.Connected || node.PendingDelete || node.Action == models.NODE_DELETE {
|
|
|
continue
|
|
|
}
|
|
|
- currentPeers, err := GetNetworkNodes(node.Network)
|
|
|
- if err != nil {
|
|
|
- log.Println("no network nodes")
|
|
|
- return models.HostPeerUpdate{}, err
|
|
|
- }
|
|
|
+ currentPeers := GetNetworkNodesMemory(allNodes, node.Network)
|
|
|
var nodePeerMap map[string]models.PeerRouteInfo
|
|
|
if node.IsIngressGateway || node.IsEgressGateway {
|
|
|
nodePeerMap = make(map[string]models.PeerRouteInfo)
|
|
|
}
|
|
|
for _, peer := range currentPeers {
|
|
|
- peer := peer
|
|
|
- if peer.ID == node.ID {
|
|
|
- logger.Log(2, "peer update, skipping self")
|
|
|
- //skip yourself
|
|
|
- continue
|
|
|
- }
|
|
|
- if peer.Action == models.NODE_DELETE || peer.PendingDelete {
|
|
|
- deletedNodes = append(deletedNodes, peer) // track deleted node for peer update
|
|
|
- continue
|
|
|
- }
|
|
|
- var peerConfig wgtypes.PeerConfig
|
|
|
- peerHost, err := GetHost(peer.HostID.String())
|
|
|
- if err != nil {
|
|
|
- logger.Log(1, "no peer host", peer.HostID.String(), err.Error())
|
|
|
- return models.HostPeerUpdate{}, err
|
|
|
- }
|
|
|
-
|
|
|
- if !peer.Connected {
|
|
|
- logger.Log(2, "peer update, skipping unconnected node", peer.ID.String())
|
|
|
- //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
|
|
|
+ select {
|
|
|
+ case <-ctx.Done():
|
|
|
+ logger.Log(2, "cancelled peer update for host", host.Name, host.ID.String())
|
|
|
+ return models.HostPeerUpdate{}, fmt.Errorf("peer update cancelled")
|
|
|
+ default:
|
|
|
+ peer := peer
|
|
|
+ if peer.ID.String() == node.ID.String() {
|
|
|
+ logger.Log(2, "peer update, skipping self")
|
|
|
+ //skip yourself
|
|
|
+ continue
|
|
|
}
|
|
|
- if node.LocalAddress.String() == peer.LocalAddress.String() {
|
|
|
- uselocal = false
|
|
|
+ var peerConfig wgtypes.PeerConfig
|
|
|
+ peerHost, err := GetHost(peer.HostID.String())
|
|
|
+ if err != nil {
|
|
|
+ logger.Log(1, "no peer host", peer.HostID.String(), err.Error())
|
|
|
+ return models.HostPeerUpdate{}, err
|
|
|
}
|
|
|
- }
|
|
|
- peerConfig.Endpoint = &net.UDPAddr{
|
|
|
- IP: peerHost.EndpointIP,
|
|
|
- Port: GetPeerListenPort(peerHost),
|
|
|
- }
|
|
|
|
|
|
- if uselocal {
|
|
|
- peerConfig.Endpoint.IP = peer.LocalAddress.IP
|
|
|
- }
|
|
|
- allowedips := GetAllowedIPs(&node, &peer, nil)
|
|
|
- if peer.IsIngressGateway {
|
|
|
- for _, entry := range peer.IngressGatewayRange {
|
|
|
- _, cidr, err := net.ParseCIDR(string(entry))
|
|
|
- if err == nil {
|
|
|
- allowedips = append(allowedips, *cidr)
|
|
|
+ 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
|
|
|
}
|
|
|
}
|
|
|
- }
|
|
|
- if peer.IsEgressGateway {
|
|
|
- allowedips = append(allowedips, getEgressIPs(&node, &peer)...)
|
|
|
- }
|
|
|
- peerConfig.AllowedIPs = allowedips
|
|
|
- if node.IsIngressGateway || node.IsEgressGateway {
|
|
|
+ peerConfig.Endpoint = &net.UDPAddr{
|
|
|
+ IP: peerHost.EndpointIP,
|
|
|
+ Port: GetPeerListenPort(peerHost),
|
|
|
+ }
|
|
|
+
|
|
|
+ if uselocal {
|
|
|
+ peerConfig.Endpoint.IP = peer.LocalAddress.IP
|
|
|
+ }
|
|
|
+ allowedips := GetAllowedIPs(&node, &peer, nil)
|
|
|
if peer.IsIngressGateway {
|
|
|
- _, extPeerIDAndAddrs, err := getExtPeers(&peer)
|
|
|
- if err == nil {
|
|
|
- for _, extPeerIdAndAddr := range extPeerIDAndAddrs {
|
|
|
- extPeerIdAndAddr := extPeerIdAndAddr
|
|
|
- nodePeerMap[extPeerIdAndAddr.ID] = models.PeerRouteInfo{
|
|
|
- PeerAddr: net.IPNet{
|
|
|
- IP: net.ParseIP(extPeerIdAndAddr.Address),
|
|
|
- Mask: getCIDRMaskFromAddr(extPeerIdAndAddr.Address),
|
|
|
- },
|
|
|
- PeerKey: extPeerIdAndAddr.ID,
|
|
|
- Allow: true,
|
|
|
- }
|
|
|
+ for _, entry := range peer.IngressGatewayRange {
|
|
|
+ _, cidr, err := net.ParseCIDR(string(entry))
|
|
|
+ if err == nil {
|
|
|
+ allowedips = append(allowedips, *cidr)
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
- if node.IsIngressGateway && peer.IsEgressGateway {
|
|
|
- hostPeerUpdate.IngressInfo.EgressRanges = append(hostPeerUpdate.IngressInfo.EgressRanges,
|
|
|
- peer.EgressGatewayRanges...)
|
|
|
+ if peer.IsEgressGateway {
|
|
|
+ allowedips = append(allowedips, getEgressIPs(&node, &peer)...)
|
|
|
}
|
|
|
- nodePeerMap[peerHost.PublicKey.String()] = models.PeerRouteInfo{
|
|
|
- PeerAddr: net.IPNet{
|
|
|
- IP: net.ParseIP(peer.PrimaryAddress()),
|
|
|
- Mask: getCIDRMaskFromAddr(peer.PrimaryAddress()),
|
|
|
- },
|
|
|
- PeerKey: peerHost.PublicKey.String(),
|
|
|
- Allow: true,
|
|
|
+ if peer.Action != models.NODE_DELETE &&
|
|
|
+ !peer.PendingDelete &&
|
|
|
+ peer.Connected &&
|
|
|
+ nodeacls.AreNodesAllowed(nodeacls.NetworkID(node.Network), nodeacls.NodeID(node.ID.String()), nodeacls.NodeID(peer.ID.String())) &&
|
|
|
+ (deletedNode == nil || (deletedNode != nil && peer.ID.String() != deletedNode.ID.String())) {
|
|
|
+ peerConfig.AllowedIPs = allowedips // only append allowed IPs if valid connection
|
|
|
}
|
|
|
- }
|
|
|
|
|
|
- var nodePeer wgtypes.PeerConfig
|
|
|
- if _, ok := hostPeerUpdate.HostPeerIDs[peerHost.PublicKey.String()]; !ok {
|
|
|
- hostPeerUpdate.HostPeerIDs[peerHost.PublicKey.String()] = make(map[string]models.IDandAddr)
|
|
|
- hostPeerUpdate.Peers = append(hostPeerUpdate.Peers, peerConfig)
|
|
|
- peerIndexMap[peerHost.PublicKey.String()] = len(hostPeerUpdate.Peers) - 1
|
|
|
- hostPeerUpdate.HostPeerIDs[peerHost.PublicKey.String()][peer.ID.String()] = models.IDandAddr{
|
|
|
- ID: peer.ID.String(),
|
|
|
- Address: peer.PrimaryAddress(),
|
|
|
- Name: peerHost.Name,
|
|
|
- Network: peer.Network,
|
|
|
- }
|
|
|
- nodePeer = peerConfig
|
|
|
- } else {
|
|
|
- peerAllowedIPs := hostPeerUpdate.Peers[peerIndexMap[peerHost.PublicKey.String()]].AllowedIPs
|
|
|
- peerAllowedIPs = append(peerAllowedIPs, allowedips...)
|
|
|
- hostPeerUpdate.Peers[peerIndexMap[peerHost.PublicKey.String()]].AllowedIPs = peerAllowedIPs
|
|
|
- hostPeerUpdate.HostPeerIDs[peerHost.PublicKey.String()][peer.ID.String()] = models.IDandAddr{
|
|
|
- ID: peer.ID.String(),
|
|
|
- Address: peer.PrimaryAddress(),
|
|
|
- Name: peerHost.Name,
|
|
|
- Network: peer.Network,
|
|
|
- }
|
|
|
- nodePeer = hostPeerUpdate.Peers[peerIndexMap[peerHost.PublicKey.String()]]
|
|
|
- }
|
|
|
-
|
|
|
- if node.Network == network { // add to peers map for metrics
|
|
|
- hostPeerUpdate.PeerIDs[peerHost.PublicKey.String()] = models.IDandAddr{
|
|
|
- ID: peer.ID.String(),
|
|
|
- Address: peer.PrimaryAddress(),
|
|
|
- Name: peerHost.Name,
|
|
|
- Network: peer.Network,
|
|
|
- }
|
|
|
- hostPeerUpdate.NodePeers = append(hostPeerUpdate.NodePeers, nodePeer)
|
|
|
- }
|
|
|
- }
|
|
|
- var extPeers []wgtypes.PeerConfig
|
|
|
- var extPeerIDAndAddrs []models.IDandAddr
|
|
|
- if node.IsIngressGateway {
|
|
|
- extPeers, extPeerIDAndAddrs, err = getExtPeers(&node)
|
|
|
- if err == nil {
|
|
|
- for _, extPeerIdAndAddr := range extPeerIDAndAddrs {
|
|
|
- extPeerIdAndAddr := extPeerIdAndAddr
|
|
|
- nodePeerMap[extPeerIdAndAddr.ID] = models.PeerRouteInfo{
|
|
|
+ if node.IsIngressGateway || node.IsEgressGateway {
|
|
|
+ if peer.IsIngressGateway {
|
|
|
+ _, extPeerIDAndAddrs, err := getExtPeers(&peer)
|
|
|
+ if err == nil {
|
|
|
+ for _, extPeerIdAndAddr := range extPeerIDAndAddrs {
|
|
|
+ extPeerIdAndAddr := extPeerIdAndAddr
|
|
|
+ nodePeerMap[extPeerIdAndAddr.ID] = models.PeerRouteInfo{
|
|
|
+ PeerAddr: net.IPNet{
|
|
|
+ IP: net.ParseIP(extPeerIdAndAddr.Address),
|
|
|
+ Mask: getCIDRMaskFromAddr(extPeerIdAndAddr.Address),
|
|
|
+ },
|
|
|
+ PeerKey: extPeerIdAndAddr.ID,
|
|
|
+ Allow: true,
|
|
|
+ ID: extPeerIdAndAddr.ID,
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if node.IsIngressGateway && peer.IsEgressGateway {
|
|
|
+ hostPeerUpdate.IngressInfo.EgressRanges = append(hostPeerUpdate.IngressInfo.EgressRanges,
|
|
|
+ peer.EgressGatewayRanges...)
|
|
|
+ }
|
|
|
+ nodePeerMap[peerHost.PublicKey.String()] = models.PeerRouteInfo{
|
|
|
PeerAddr: net.IPNet{
|
|
|
- IP: net.ParseIP(extPeerIdAndAddr.Address),
|
|
|
- Mask: getCIDRMaskFromAddr(extPeerIdAndAddr.Address),
|
|
|
+ IP: net.ParseIP(peer.PrimaryAddress()),
|
|
|
+ Mask: getCIDRMaskFromAddr(peer.PrimaryAddress()),
|
|
|
},
|
|
|
- PeerKey: extPeerIdAndAddr.ID,
|
|
|
+ PeerKey: peerHost.PublicKey.String(),
|
|
|
Allow: true,
|
|
|
+ ID: peer.ID.String(),
|
|
|
}
|
|
|
}
|
|
|
- hostPeerUpdate.Peers = append(hostPeerUpdate.Peers, extPeers...)
|
|
|
- for _, extPeerIdAndAddr := range extPeerIDAndAddrs {
|
|
|
- extPeerIdAndAddr := extPeerIdAndAddr
|
|
|
- hostPeerUpdate.HostPeerIDs[extPeerIdAndAddr.ID] = make(map[string]models.IDandAddr)
|
|
|
- hostPeerUpdate.HostPeerIDs[extPeerIdAndAddr.ID][extPeerIdAndAddr.ID] = models.IDandAddr{
|
|
|
- ID: extPeerIdAndAddr.ID,
|
|
|
- Address: extPeerIdAndAddr.Address,
|
|
|
- Name: extPeerIdAndAddr.Name,
|
|
|
- Network: node.Network,
|
|
|
+
|
|
|
+ peerProxyPort := GetProxyListenPort(peerHost)
|
|
|
+ var nodePeer wgtypes.PeerConfig
|
|
|
+ if _, ok := hostPeerUpdate.HostPeerIDs[peerHost.PublicKey.String()]; !ok {
|
|
|
+ hostPeerUpdate.HostPeerIDs[peerHost.PublicKey.String()] = make(map[string]models.IDandAddr)
|
|
|
+ hostPeerUpdate.Peers = append(hostPeerUpdate.Peers, peerConfig)
|
|
|
+ peerIndexMap[peerHost.PublicKey.String()] = len(hostPeerUpdate.Peers) - 1
|
|
|
+ hostPeerUpdate.HostPeerIDs[peerHost.PublicKey.String()][peer.ID.String()] = models.IDandAddr{
|
|
|
+ ID: peer.ID.String(),
|
|
|
+ Address: peer.PrimaryAddress(),
|
|
|
+ Name: peerHost.Name,
|
|
|
+ Network: peer.Network,
|
|
|
+ ProxyListenPort: peerProxyPort,
|
|
|
}
|
|
|
- hostPeerUpdate.IngressInfo.ExtPeers[extPeerIdAndAddr.ID] = models.ExtClientInfo{
|
|
|
- Masquerade: true,
|
|
|
- IngGwAddr: net.IPNet{
|
|
|
- IP: net.ParseIP(node.PrimaryAddress()),
|
|
|
- Mask: getCIDRMaskFromAddr(node.PrimaryAddress()),
|
|
|
- },
|
|
|
- Network: node.PrimaryNetworkRange(),
|
|
|
- ExtPeerAddr: net.IPNet{
|
|
|
- IP: net.ParseIP(extPeerIdAndAddr.Address),
|
|
|
- Mask: getCIDRMaskFromAddr(extPeerIdAndAddr.Address),
|
|
|
- },
|
|
|
- ExtPeerKey: extPeerIdAndAddr.ID,
|
|
|
- Peers: nodePeerMap,
|
|
|
+ hostPeerUpdate.HostNetworkInfo[peerHost.PublicKey.String()] = models.HostNetworkInfo{
|
|
|
+ Interfaces: peerHost.Interfaces,
|
|
|
+ ProxyListenPort: peerProxyPort,
|
|
|
+ }
|
|
|
+ nodePeer = peerConfig
|
|
|
+ } else {
|
|
|
+ peerAllowedIPs := hostPeerUpdate.Peers[peerIndexMap[peerHost.PublicKey.String()]].AllowedIPs
|
|
|
+ peerAllowedIPs = append(peerAllowedIPs, allowedips...)
|
|
|
+ hostPeerUpdate.Peers[peerIndexMap[peerHost.PublicKey.String()]].AllowedIPs = peerAllowedIPs
|
|
|
+ hostPeerUpdate.HostPeerIDs[peerHost.PublicKey.String()][peer.ID.String()] = models.IDandAddr{
|
|
|
+ ID: peer.ID.String(),
|
|
|
+ Address: peer.PrimaryAddress(),
|
|
|
+ Name: peerHost.Name,
|
|
|
+ Network: peer.Network,
|
|
|
+ ProxyListenPort: GetProxyListenPort(peerHost),
|
|
|
}
|
|
|
- if node.Network == network {
|
|
|
- hostPeerUpdate.PeerIDs[extPeerIdAndAddr.ID] = extPeerIdAndAddr
|
|
|
- hostPeerUpdate.NodePeers = append(hostPeerUpdate.NodePeers, extPeers...)
|
|
|
+ hostPeerUpdate.HostNetworkInfo[peerHost.PublicKey.String()] = models.HostNetworkInfo{
|
|
|
+ Interfaces: peerHost.Interfaces,
|
|
|
+ ProxyListenPort: peerProxyPort,
|
|
|
}
|
|
|
+ nodePeer = hostPeerUpdate.Peers[peerIndexMap[peerHost.PublicKey.String()]]
|
|
|
+ }
|
|
|
+
|
|
|
+ if node.Network == network { // add to peers map for metrics
|
|
|
+ hostPeerUpdate.PeerIDs[peerHost.PublicKey.String()] = models.IDandAddr{
|
|
|
+ ID: peer.ID.String(),
|
|
|
+ Address: peer.PrimaryAddress(),
|
|
|
+ Name: peerHost.Name,
|
|
|
+ Network: peer.Network,
|
|
|
+ ProxyListenPort: peerHost.ProxyListenPort,
|
|
|
+ }
|
|
|
+ hostPeerUpdate.NodePeers = append(hostPeerUpdate.NodePeers, nodePeer)
|
|
|
}
|
|
|
- } else if !database.IsEmptyRecord(err) {
|
|
|
- logger.Log(1, "error retrieving external clients:", err.Error())
|
|
|
- }
|
|
|
- }
|
|
|
- if node.IsEgressGateway {
|
|
|
- hostPeerUpdate.EgressInfo[node.ID.String()] = models.EgressInfo{
|
|
|
- EgressID: node.ID.String(),
|
|
|
- Network: node.PrimaryNetworkRange(),
|
|
|
- EgressGwAddr: net.IPNet{
|
|
|
- IP: net.ParseIP(node.PrimaryAddress()),
|
|
|
- Mask: getCIDRMaskFromAddr(node.PrimaryAddress()),
|
|
|
- },
|
|
|
- GwPeers: nodePeerMap,
|
|
|
- EgressGWCfg: node.EgressGatewayRequest,
|
|
|
}
|
|
|
- }
|
|
|
- }
|
|
|
+ var extPeers []wgtypes.PeerConfig
|
|
|
+ var extPeerIDAndAddrs []models.IDandAddr
|
|
|
+ if node.IsIngressGateway {
|
|
|
+ extPeers, extPeerIDAndAddrs, err = getExtPeers(&node)
|
|
|
+ if err == nil {
|
|
|
+ for _, extPeerIdAndAddr := range extPeerIDAndAddrs {
|
|
|
+ extPeerIdAndAddr := extPeerIdAndAddr
|
|
|
+ nodePeerMap[extPeerIdAndAddr.ID] = models.PeerRouteInfo{
|
|
|
+ PeerAddr: net.IPNet{
|
|
|
+ IP: net.ParseIP(extPeerIdAndAddr.Address),
|
|
|
+ Mask: getCIDRMaskFromAddr(extPeerIdAndAddr.Address),
|
|
|
+ },
|
|
|
+ PeerKey: extPeerIdAndAddr.ID,
|
|
|
+ Allow: true,
|
|
|
+ ID: extPeerIdAndAddr.ID,
|
|
|
+ }
|
|
|
+ }
|
|
|
+ hostPeerUpdate.Peers = append(hostPeerUpdate.Peers, extPeers...)
|
|
|
+ for _, extPeerIdAndAddr := range extPeerIDAndAddrs {
|
|
|
+ extPeerIdAndAddr := extPeerIdAndAddr
|
|
|
+ hostPeerUpdate.HostPeerIDs[extPeerIdAndAddr.ID] = make(map[string]models.IDandAddr)
|
|
|
+ hostPeerUpdate.HostPeerIDs[extPeerIdAndAddr.ID][extPeerIdAndAddr.ID] = models.IDandAddr{
|
|
|
+ ID: extPeerIdAndAddr.ID,
|
|
|
+ Address: extPeerIdAndAddr.Address,
|
|
|
+ Name: extPeerIdAndAddr.Name,
|
|
|
+ Network: node.Network,
|
|
|
+ }
|
|
|
|
|
|
- // run through delete nodes
|
|
|
- if len(deletedNodes) > 0 {
|
|
|
- for i := range deletedNodes {
|
|
|
- delNode := deletedNodes[i]
|
|
|
- delHost, err := GetHost(delNode.HostID.String())
|
|
|
- if err != nil {
|
|
|
- continue
|
|
|
+ hostPeerUpdate.IngressInfo.ExtPeers[extPeerIdAndAddr.ID] = models.ExtClientInfo{
|
|
|
+ Masquerade: true,
|
|
|
+ IngGwAddr: net.IPNet{
|
|
|
+ IP: net.ParseIP(node.PrimaryAddress()),
|
|
|
+ Mask: getCIDRMaskFromAddr(node.PrimaryAddress()),
|
|
|
+ },
|
|
|
+ Network: node.PrimaryNetworkRange(),
|
|
|
+ ExtPeerAddr: net.IPNet{
|
|
|
+ IP: net.ParseIP(extPeerIdAndAddr.Address),
|
|
|
+ Mask: getCIDRMaskFromAddr(extPeerIdAndAddr.Address),
|
|
|
+ },
|
|
|
+ ExtPeerKey: extPeerIdAndAddr.ID,
|
|
|
+ Peers: filterNodeMapForClientACLs(extPeerIdAndAddr.ID, node.Network, nodePeerMap),
|
|
|
+ }
|
|
|
+ if node.Network == network {
|
|
|
+ hostPeerUpdate.PeerIDs[extPeerIdAndAddr.ID] = extPeerIdAndAddr
|
|
|
+ hostPeerUpdate.NodePeers = append(hostPeerUpdate.NodePeers, extPeers...)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } else if !database.IsEmptyRecord(err) {
|
|
|
+ logger.Log(1, "error retrieving external clients:", err.Error())
|
|
|
+ }
|
|
|
}
|
|
|
- if _, ok := hostPeerUpdate.HostPeerIDs[delHost.PublicKey.String()]; !ok {
|
|
|
- var peerConfig = wgtypes.PeerConfig{}
|
|
|
- peerConfig.PublicKey = delHost.PublicKey
|
|
|
- peerConfig.Endpoint = &net.UDPAddr{
|
|
|
- IP: delHost.EndpointIP,
|
|
|
- Port: GetPeerListenPort(delHost),
|
|
|
+ if node.IsEgressGateway {
|
|
|
+ hostPeerUpdate.EgressInfo[node.ID.String()] = models.EgressInfo{
|
|
|
+ EgressID: node.ID.String(),
|
|
|
+ Network: node.PrimaryNetworkRange(),
|
|
|
+ EgressGwAddr: net.IPNet{
|
|
|
+ IP: net.ParseIP(node.PrimaryAddress()),
|
|
|
+ Mask: getCIDRMaskFromAddr(node.PrimaryAddress()),
|
|
|
+ },
|
|
|
+ GwPeers: nodePeerMap,
|
|
|
+ EgressGWCfg: node.EgressGatewayRequest,
|
|
|
}
|
|
|
- peerConfig.Remove = true
|
|
|
- peerConfig.AllowedIPs = []net.IPNet{delNode.Address, delNode.Address6}
|
|
|
- hostPeerUpdate.Peers = append(hostPeerUpdate.Peers, peerConfig)
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
+ // == post peer calculations ==
|
|
|
+ // indicate removal if no allowed IPs were calculated
|
|
|
+ for i := range hostPeerUpdate.Peers {
|
|
|
+ peer := hostPeerUpdate.Peers[i]
|
|
|
+ if len(peer.AllowedIPs) == 0 {
|
|
|
+ peer.Remove = true
|
|
|
+ }
|
|
|
+ hostPeerUpdate.Peers[i] = peer
|
|
|
+ }
|
|
|
+
|
|
|
+ for i := range hostPeerUpdate.NodePeers {
|
|
|
+ peer := hostPeerUpdate.NodePeers[i]
|
|
|
+ if len(peer.AllowedIPs) == 0 {
|
|
|
+ peer.Remove = true
|
|
|
+ }
|
|
|
+ hostPeerUpdate.NodePeers[i] = peer
|
|
|
+ }
|
|
|
+
|
|
|
+ if deletedClient != nil {
|
|
|
+ key, err := wgtypes.ParseKey(deletedClient.PublicKey)
|
|
|
+ if err == nil {
|
|
|
+ hostPeerUpdate.Peers = append(hostPeerUpdate.Peers, wgtypes.PeerConfig{
|
|
|
+ PublicKey: key,
|
|
|
+ Remove: true,
|
|
|
+ })
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
return hostPeerUpdate, nil
|
|
|
}
|
|
@@ -393,6 +434,15 @@ func GetPeerListenPort(host *models.Host) int {
|
|
|
return peerPort
|
|
|
}
|
|
|
|
|
|
+// GetProxyListenPort - fetches the proxy listen port
|
|
|
+func GetProxyListenPort(host *models.Host) int {
|
|
|
+ proxyPort := host.ProxyListenPort
|
|
|
+ if host.PublicListenPort != 0 {
|
|
|
+ proxyPort = host.PublicListenPort
|
|
|
+ }
|
|
|
+ return proxyPort
|
|
|
+}
|
|
|
+
|
|
|
func getExtPeers(node *models.Node) ([]wgtypes.PeerConfig, []models.IDandAddr, error) {
|
|
|
var peers []wgtypes.PeerConfig
|
|
|
var idsAndAddr []models.IDandAddr
|
|
@@ -405,6 +455,7 @@ func getExtPeers(node *models.Node) ([]wgtypes.PeerConfig, []models.IDandAddr, e
|
|
|
return peers, idsAndAddr, err
|
|
|
}
|
|
|
for _, extPeer := range extPeers {
|
|
|
+ extPeer := extPeer
|
|
|
pubkey, err := wgtypes.ParseKey(extPeer.PublicKey)
|
|
|
if err != nil {
|
|
|
logger.Log(1, "error parsing ext pub key:", err.Error())
|
|
@@ -636,3 +687,29 @@ func getCIDRMaskFromAddr(addr string) net.IPMask {
|
|
|
}
|
|
|
return cidr
|
|
|
}
|
|
|
+
|
|
|
+// accounts for ext client ACLs
|
|
|
+func filterNodeMapForClientACLs(publicKey, network string, nodePeerMap map[string]models.PeerRouteInfo) map[string]models.PeerRouteInfo {
|
|
|
+ if !isEE {
|
|
|
+ return nodePeerMap
|
|
|
+ }
|
|
|
+ if nodePeerMap == nil {
|
|
|
+ return map[string]models.PeerRouteInfo{}
|
|
|
+ }
|
|
|
+
|
|
|
+ if len(publicKey) == 0 || len(network) == 0 {
|
|
|
+ return nodePeerMap
|
|
|
+ }
|
|
|
+
|
|
|
+ client, err := GetExtClientByPubKey(publicKey, network)
|
|
|
+ if err != nil {
|
|
|
+ return nodePeerMap
|
|
|
+ }
|
|
|
+ for k := range nodePeerMap {
|
|
|
+ currNodePeer := nodePeerMap[k]
|
|
|
+ if _, ok := client.ACLs[currNodePeer.ID]; ok {
|
|
|
+ delete(nodePeerMap, k)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return nodePeerMap
|
|
|
+}
|