Browse Source

Merge pull request #660 from gravitl/bugfix_v0.10.0_fix_timing

Bugfix v0.10.0 fix timing
Alex Feiszli 3 years ago
parent
commit
062dcd1468

+ 3 - 1
controllers/network.go

@@ -225,7 +225,8 @@ func createNetwork(w http.ResponseWriter, r *http.Request) {
 	}
 	}
 
 
 	if servercfg.IsClientMode() != "off" {
 	if servercfg.IsClientMode() != "off" {
-		err = logic.ServerJoin(&network)
+		var node models.Node
+		node, err = logic.ServerJoin(&network)
 		if err != nil {
 		if err != nil {
 			logic.DeleteNetwork(network.NetID)
 			logic.DeleteNetwork(network.NetID)
 			if err == nil {
 			if err == nil {
@@ -234,6 +235,7 @@ func createNetwork(w http.ResponseWriter, r *http.Request) {
 			returnErrorResponse(w, r, formatError(err, "internal"))
 			returnErrorResponse(w, r, formatError(err, "internal"))
 			return
 			return
 		}
 		}
+		getServerAddrs(&node)
 	}
 	}
 
 
 	logger.Log(1, r.Header.Get("user"), "created network", network.NetID)
 	logger.Log(1, r.Header.Get("user"), "created network", network.NetID)

+ 41 - 77
controllers/node.go

@@ -2,6 +2,7 @@ package controller
 
 
 import (
 import (
 	"encoding/json"
 	"encoding/json"
+	"fmt"
 	"net/http"
 	"net/http"
 	"strings"
 	"strings"
 
 
@@ -12,7 +13,6 @@ import (
 	"github.com/gravitl/netmaker/logic"
 	"github.com/gravitl/netmaker/logic"
 	"github.com/gravitl/netmaker/models"
 	"github.com/gravitl/netmaker/models"
 	"github.com/gravitl/netmaker/mq"
 	"github.com/gravitl/netmaker/mq"
-	"github.com/gravitl/netmaker/netclient/ncutils"
 	"github.com/gravitl/netmaker/servercfg"
 	"github.com/gravitl/netmaker/servercfg"
 	"golang.org/x/crypto/bcrypt"
 	"golang.org/x/crypto/bcrypt"
 )
 )
@@ -407,13 +407,11 @@ func createNode(w http.ResponseWriter, r *http.Request) {
 		return
 		return
 	}
 	}
 
 
-	if err = runServerPeerUpdate(node.Network, isServer(&node), "node create"); err != nil {
-		logger.Log(1, "internal error when creating node:", node.ID)
-	}
-
 	logger.Log(1, r.Header.Get("user"), "created new node", node.Name, "on network", node.Network)
 	logger.Log(1, r.Header.Get("user"), "created new node", node.Name, "on network", node.Network)
 	w.WriteHeader(http.StatusOK)
 	w.WriteHeader(http.StatusOK)
 	json.NewEncoder(w).Encode(node)
 	json.NewEncoder(w).Encode(node)
+
+	runUpdates(&node, false)
 }
 }
 
 
 //Takes node out of pending state
 //Takes node out of pending state
@@ -427,20 +425,11 @@ func uncordonNode(w http.ResponseWriter, r *http.Request) {
 		returnErrorResponse(w, r, formatError(err, "internal"))
 		returnErrorResponse(w, r, formatError(err, "internal"))
 		return
 		return
 	}
 	}
-	if err = runServerPeerUpdate(node.Network, isServer(&node), "node uncordon"); err != nil {
-		logger.Log(1, "internal error when approving node:", nodeid)
-	}
-	go func() {
-		if err := mq.NodeUpdate(&node); err != nil {
-			logger.Log(1, "error publishing node update", err.Error())
-		}
-		if err := mq.PublishPeerUpdate(&node); err != nil {
-			logger.Log(1, "error publishing peer update ", err.Error())
-		}
-	}()
 	logger.Log(1, r.Header.Get("user"), "uncordoned node", node.Name)
 	logger.Log(1, r.Header.Get("user"), "uncordoned node", node.Name)
 	w.WriteHeader(http.StatusOK)
 	w.WriteHeader(http.StatusOK)
 	json.NewEncoder(w).Encode("SUCCESS")
 	json.NewEncoder(w).Encode("SUCCESS")
+
+	runUpdates(&node, true)
 }
 }
 
 
 func createEgressGateway(w http.ResponseWriter, r *http.Request) {
 func createEgressGateway(w http.ResponseWriter, r *http.Request) {
@@ -459,20 +448,12 @@ func createEgressGateway(w http.ResponseWriter, r *http.Request) {
 		returnErrorResponse(w, r, formatError(err, "internal"))
 		returnErrorResponse(w, r, formatError(err, "internal"))
 		return
 		return
 	}
 	}
-	if err = runServerPeerUpdate(gateway.NetID, isServer(&node), "node egress create"); err != nil {
-		logger.Log(1, "internal error when setting peers after creating egress on node:", gateway.NodeID)
-	}
-	go func() {
-		if err := mq.NodeUpdate(&node); err != nil {
-			logger.Log(1, "error publishing node update", err.Error())
-		}
-		if err := mq.PublishPeerUpdate(&node); err != nil {
-			logger.Log(1, "error publishing peer update "+err.Error())
-		}
-	}()
+
 	logger.Log(1, r.Header.Get("user"), "created egress gateway on node", gateway.NodeID, "on network", gateway.NetID)
 	logger.Log(1, r.Header.Get("user"), "created egress gateway on node", gateway.NodeID, "on network", gateway.NetID)
 	w.WriteHeader(http.StatusOK)
 	w.WriteHeader(http.StatusOK)
 	json.NewEncoder(w).Encode(node)
 	json.NewEncoder(w).Encode(node)
+
+	runUpdates(&node, true)
 }
 }
 
 
 func deleteEgressGateway(w http.ResponseWriter, r *http.Request) {
 func deleteEgressGateway(w http.ResponseWriter, r *http.Request) {
@@ -485,20 +466,12 @@ func deleteEgressGateway(w http.ResponseWriter, r *http.Request) {
 		returnErrorResponse(w, r, formatError(err, "internal"))
 		returnErrorResponse(w, r, formatError(err, "internal"))
 		return
 		return
 	}
 	}
-	if err = runServerPeerUpdate(netid, isServer(&node), "egress delete"); err != nil {
-		logger.Log(1, "internal error when setting peers after removing egress on node:", nodeid)
-	}
-	go func() {
-		if err := mq.NodeUpdate(&node); err != nil {
-			logger.Log(1, "error publishing node update", err.Error())
-		}
-		if err := mq.PublishPeerUpdate(&node); err != nil {
-			logger.Log(1, "error publishing peer update ", err.Error())
-		}
-	}()
+
 	logger.Log(1, r.Header.Get("user"), "deleted egress gateway", nodeid, "on network", netid)
 	logger.Log(1, r.Header.Get("user"), "deleted egress gateway", nodeid, "on network", netid)
 	w.WriteHeader(http.StatusOK)
 	w.WriteHeader(http.StatusOK)
 	json.NewEncoder(w).Encode(node)
 	json.NewEncoder(w).Encode(node)
+
+	runUpdates(&node, true)
 }
 }
 
 
 // == INGRESS ==
 // == INGRESS ==
@@ -513,17 +486,12 @@ func createIngressGateway(w http.ResponseWriter, r *http.Request) {
 		returnErrorResponse(w, r, formatError(err, "internal"))
 		returnErrorResponse(w, r, formatError(err, "internal"))
 		return
 		return
 	}
 	}
-	go func() {
-		if err := mq.NodeUpdate(&node); err != nil {
-			logger.Log(1, "error publishing node update", err.Error())
-		}
-		if err := mq.PublishPeerUpdate(&node); err != nil {
-			logger.Log(1, "error publishing peer update ", err.Error())
-		}
-	}()
+
 	logger.Log(1, r.Header.Get("user"), "created ingress gateway on node", nodeid, "on network", netid)
 	logger.Log(1, r.Header.Get("user"), "created ingress gateway on node", nodeid, "on network", netid)
 	w.WriteHeader(http.StatusOK)
 	w.WriteHeader(http.StatusOK)
 	json.NewEncoder(w).Encode(node)
 	json.NewEncoder(w).Encode(node)
+
+	runUpdates(&node, true)
 }
 }
 
 
 func deleteIngressGateway(w http.ResponseWriter, r *http.Request) {
 func deleteIngressGateway(w http.ResponseWriter, r *http.Request) {
@@ -535,17 +503,12 @@ func deleteIngressGateway(w http.ResponseWriter, r *http.Request) {
 		returnErrorResponse(w, r, formatError(err, "internal"))
 		returnErrorResponse(w, r, formatError(err, "internal"))
 		return
 		return
 	}
 	}
-	go func() {
-		if err := mq.NodeUpdate(&node); err != nil {
-			logger.Log(1, "error publishing node update", err.Error())
-		}
-		if err := mq.PublishPeerUpdate(&node); err != nil {
-			logger.Log(1, "error publishing peer update ", err.Error())
-		}
-	}()
+
 	logger.Log(1, r.Header.Get("user"), "deleted ingress gateway", nodeid)
 	logger.Log(1, r.Header.Get("user"), "deleted ingress gateway", nodeid)
 	w.WriteHeader(http.StatusOK)
 	w.WriteHeader(http.StatusOK)
 	json.NewEncoder(w).Encode(node)
 	json.NewEncoder(w).Encode(node)
+
+	runUpdates(&node, true)
 }
 }
 
 
 func updateNode(w http.ResponseWriter, r *http.Request) {
 func updateNode(w http.ResponseWriter, r *http.Request) {
@@ -587,8 +550,6 @@ func updateNode(w http.ResponseWriter, r *http.Request) {
 		newNode.PostUp = node.PostUp
 		newNode.PostUp = node.PostUp
 	}
 	}
 
 
-	var shouldPeersUpdate = ncutils.IfaceDelta(&node, &newNode)
-
 	err = logic.UpdateNode(&node, &newNode)
 	err = logic.UpdateNode(&node, &newNode)
 	if err != nil {
 	if err != nil {
 		returnErrorResponse(w, r, formatError(err, "internal"))
 		returnErrorResponse(w, r, formatError(err, "internal"))
@@ -605,24 +566,11 @@ func updateNode(w http.ResponseWriter, r *http.Request) {
 		err = logic.SetDNS()
 		err = logic.SetDNS()
 	}
 	}
 
 
-	err = runServerPeerUpdate(node.Network, shouldPeersUpdate, "node update")
-	if err != nil {
-		returnErrorResponse(w, r, formatError(err, "internal"))
-		return
-	}
 	logger.Log(1, r.Header.Get("user"), "updated node", node.MacAddress, "on network", node.Network)
 	logger.Log(1, r.Header.Get("user"), "updated node", node.MacAddress, "on network", node.Network)
 	w.WriteHeader(http.StatusOK)
 	w.WriteHeader(http.StatusOK)
 	json.NewEncoder(w).Encode(newNode)
 	json.NewEncoder(w).Encode(newNode)
-	go func() {
-		if err := mq.NodeUpdate(&newNode); err != nil {
-			logger.Log(1, "error publishing node update", err.Error())
-		}
-		if shouldPeersUpdate {
-			if err := mq.PublishPeerUpdate(&newNode); err != nil {
-				logger.Log(1, "error publishing peer update after node update", err.Error())
-			}
-		}
-	}()
+
+	runUpdates(&newNode, true)
 }
 }
 
 
 func deleteNode(w http.ResponseWriter, r *http.Request) {
 func deleteNode(w http.ResponseWriter, r *http.Request) {
@@ -637,23 +585,39 @@ func deleteNode(w http.ResponseWriter, r *http.Request) {
 		returnErrorResponse(w, r, formatError(err, "badrequest"))
 		returnErrorResponse(w, r, formatError(err, "badrequest"))
 		return
 		return
 	}
 	}
+	if isServer(&node) {
+		returnErrorResponse(w, r, formatError(fmt.Errorf("cannot delete server node"), "badrequest"))
+		return
+	}
 	err = logic.DeleteNodeByID(&node, false)
 	err = logic.DeleteNodeByID(&node, false)
 	if err != nil {
 	if err != nil {
 		returnErrorResponse(w, r, formatError(err, "internal"))
 		returnErrorResponse(w, r, formatError(err, "internal"))
 		return
 		return
 	}
 	}
 
 
-	err = runServerPeerUpdate(node.Network, isServer(&node), "node delete")
 	if err != nil {
 	if err != nil {
 		returnErrorResponse(w, r, formatError(err, "internal"))
 		returnErrorResponse(w, r, formatError(err, "internal"))
 		return
 		return
 	}
 	}
 	node.Action = models.NODE_DELETE
 	node.Action = models.NODE_DELETE
-	go func() {
-		if err := mq.NodeUpdate(&node); err != nil {
-			logger.Log(1, "error publishing node delete ", err.Error())
-		}
-	}()
 	logger.Log(1, r.Header.Get("user"), "Deleted node", nodeid, "from network", params["network"])
 	logger.Log(1, r.Header.Get("user"), "Deleted node", nodeid, "from network", params["network"])
 	returnSuccessResponse(w, r, nodeid+" deleted.")
 	returnSuccessResponse(w, r, nodeid+" deleted.")
+
+	runUpdates(&node, true)
+}
+
+func runUpdates(node *models.Node, nodeUpdate bool) error {
+	if nodeUpdate {
+		if err := mq.NodeUpdate(node); err != nil {
+			logger.Log(1, "error publishing node update", err.Error())
+			return err
+		}
+	}
+
+	if err := runServerPeerUpdate(node, isServer(node)); err != nil {
+		logger.Log(1, "internal error when running peer node:", err.Error())
+		return err
+	}
+
+	return nil
 }
 }

+ 37 - 45
controllers/node_grpc.go

@@ -11,9 +11,8 @@ import (
 	"github.com/gravitl/netmaker/logger"
 	"github.com/gravitl/netmaker/logger"
 	"github.com/gravitl/netmaker/logic"
 	"github.com/gravitl/netmaker/logic"
 	"github.com/gravitl/netmaker/models"
 	"github.com/gravitl/netmaker/models"
-	"github.com/gravitl/netmaker/mq"
-	"github.com/gravitl/netmaker/netclient/ncutils"
 	"github.com/gravitl/netmaker/servercfg"
 	"github.com/gravitl/netmaker/servercfg"
+	"github.com/gravitl/netmaker/serverctl"
 )
 )
 
 
 // NodeServiceServer - represents the service server for gRPC
 // NodeServiceServer - represents the service server for gRPC
@@ -32,6 +31,8 @@ func (s *NodeServiceServer) ReadNode(ctx context.Context, req *nodepb.Object) (*
 	if err != nil {
 	if err != nil {
 		return nil, err
 		return nil, err
 	}
 	}
+	getServerAddrs(&node)
+
 	node.SetLastCheckIn()
 	node.SetLastCheckIn()
 	// Cast to ReadNodeRes type
 	// Cast to ReadNodeRes type
 	nodeData, errN := json.Marshal(&node)
 	nodeData, errN := json.Marshal(&node)
@@ -68,7 +69,9 @@ func (s *NodeServiceServer) CreateNode(ctx context.Context, req *nodepb.Object)
 			return nil, errors.New("invalid key, and network does not allow no-key signups")
 			return nil, errors.New("invalid key, and network does not allow no-key signups")
 		}
 		}
 	}
 	}
+
 	getServerAddrs(&node)
 	getServerAddrs(&node)
+
 	key, keyErr := logic.RetrievePublicTrafficKey()
 	key, keyErr := logic.RetrievePublicTrafficKey()
 	if keyErr != nil {
 	if keyErr != nil {
 		logger.Log(0, "error retrieving key: ", keyErr.Error())
 		logger.Log(0, "error retrieving key: ", keyErr.Error())
@@ -95,26 +98,7 @@ func (s *NodeServiceServer) CreateNode(ctx context.Context, req *nodepb.Object)
 		Type: nodepb.NODE_TYPE,
 		Type: nodepb.NODE_TYPE,
 	}
 	}
 
 
-	network, err := logic.GetParentNetwork(node.Network)
-	if err != nil {
-		return nil, err
-	}
-	network.NodesLastModified = time.Now().Unix()
-	network.DefaultServerAddrs = node.NetworkSettings.DefaultServerAddrs
-	if err := logic.SaveNetwork(&network); err != nil {
-		return nil, err
-	}
-	err = runServerPeerUpdate(node.Network, isServer(&node), "node_grpc create")
-	if err != nil {
-		logger.Log(1, "internal error when setting peers after node,", node.ID, "was created (gRPC)")
-	}
-	logger.Log(0, "new node,", node.Name, ", added on network,"+node.Network)
-	// notify other nodes on network of new peer
-	go func() {
-		if err := mq.PublishPeerUpdate(&node); err != nil {
-			logger.Log(0, "failed to inform peers of new node ", err.Error())
-		}
-	}()
+	runUpdates(&node, false)
 
 
 	return response, nil
 	return response, nil
 }
 }
@@ -136,8 +120,7 @@ func (s *NodeServiceServer) UpdateNode(ctx context.Context, req *nodepb.Object)
 		newnode.PostDown = node.PostDown
 		newnode.PostDown = node.PostDown
 		newnode.PostUp = node.PostUp
 		newnode.PostUp = node.PostUp
 	}
 	}
-	var shouldPeersUpdate = ncutils.IfaceDelta(&node, &newnode)
-	getServerAddrs(&node)
+
 	err = logic.UpdateNode(&node, &newnode)
 	err = logic.UpdateNode(&node, &newnode)
 	if err != nil {
 	if err != nil {
 		return nil, err
 		return nil, err
@@ -146,14 +129,15 @@ func (s *NodeServiceServer) UpdateNode(ctx context.Context, req *nodepb.Object)
 	if err != nil {
 	if err != nil {
 		return nil, err
 		return nil, err
 	}
 	}
+	getServerAddrs(&newnode)
+
 	nodeData, errN := json.Marshal(&newnode)
 	nodeData, errN := json.Marshal(&newnode)
 	if errN != nil {
 	if errN != nil {
 		return nil, err
 		return nil, err
 	}
 	}
-	err = runServerPeerUpdate(newnode.Network, shouldPeersUpdate, "node_grpc update")
-	if err != nil {
-		logger.Log(1, "could not update peers on gRPC after node,", newnode.ID, "updated (gRPC), \nerror:", err.Error())
-	}
+
+	runUpdates(&newnode, false)
+
 	return &nodepb.Object{
 	return &nodepb.Object{
 		Data: string(nodeData),
 		Data: string(nodeData),
 		Type: nodepb.NODE_TYPE,
 		Type: nodepb.NODE_TYPE,
@@ -161,16 +145,33 @@ func (s *NodeServiceServer) UpdateNode(ctx context.Context, req *nodepb.Object)
 }
 }
 
 
 func getServerAddrs(node *models.Node) {
 func getServerAddrs(node *models.Node) {
-	var serverNodes = logic.GetServerNodes(node.Network)
-	var serverAddrs = make([]models.ServerAddr, len(serverNodes))
-	for i, server := range serverNodes {
-		serverAddrs[i] = models.ServerAddr{
-			IsLeader: logic.IsLeader(&server),
-			Address:  server.Address,
+	serverNodes := logic.GetServerNodes(node.Network)
+	//pubIP, _ := servercfg.GetPublicIP()
+	if len(serverNodes) == 0 {
+		if err := serverctl.SyncServerNetwork(node.Network); err != nil {
+			return
 		}
 		}
 	}
 	}
+
+	var serverAddrs = make([]models.ServerAddr, 1)
+
+	for _, node := range serverNodes {
+
+		serverAddrs = append(serverAddrs, models.ServerAddr{
+			IsLeader: logic.IsLeader(&node),
+			Address:  node.Address,
+			ID:       node.ID,
+		})
+	}
+
+	networkSettings, _ := logic.GetParentNetwork(node.Network)
 	// TODO consolidate functionality around files
 	// TODO consolidate functionality around files
-	node.NetworkSettings.DefaultServerAddrs = serverAddrs
+	networkSettings.NodesLastModified = time.Now().Unix()
+	networkSettings.DefaultServerAddrs = serverAddrs
+	if err := logic.SaveNetwork(&networkSettings); err != nil {
+		logger.Log(1, "unable to save network on serverAddr update", err.Error())
+	}
+	node.NetworkSettings.DefaultServerAddrs = networkSettings.DefaultServerAddrs
 }
 }
 
 
 // NodeServiceServer.DeleteNode - deletes a node and responds over gRPC
 // NodeServiceServer.DeleteNode - deletes a node and responds over gRPC
@@ -185,16 +186,7 @@ func (s *NodeServiceServer) DeleteNode(ctx context.Context, req *nodepb.Object)
 	if err != nil {
 	if err != nil {
 		return nil, err
 		return nil, err
 	}
 	}
-	err = runServerPeerUpdate(node.Network, false, "node_grpc delete")
-	if err != nil {
-		logger.Log(1, "internal error when setting peers after deleting node:", node.ID, "over gRPC")
-	}
-	// notify other nodes on network of deleted peer
-	go func() {
-		if err := mq.PublishPeerUpdate(&node); err != nil {
-			logger.Log(0, "failed to inform peers of deleted node ", err.Error())
-		}
-	}()
+	runServerPeerUpdate(&node, false)
 
 
 	return &nodepb.Object{
 	return &nodepb.Object{
 		Data: "success",
 		Data: "success",

+ 2 - 23
controllers/relay.go

@@ -8,7 +8,6 @@ import (
 	"github.com/gravitl/netmaker/logger"
 	"github.com/gravitl/netmaker/logger"
 	"github.com/gravitl/netmaker/logic"
 	"github.com/gravitl/netmaker/logic"
 	"github.com/gravitl/netmaker/models"
 	"github.com/gravitl/netmaker/models"
-	"github.com/gravitl/netmaker/mq"
 )
 )
 
 
 func createRelay(w http.ResponseWriter, r *http.Request) {
 func createRelay(w http.ResponseWriter, r *http.Request) {
@@ -27,20 +26,10 @@ func createRelay(w http.ResponseWriter, r *http.Request) {
 		returnErrorResponse(w, r, formatError(err, "internal"))
 		returnErrorResponse(w, r, formatError(err, "internal"))
 		return
 		return
 	}
 	}
-	if err = runServerPeerUpdate(relay.NetID, isServer(&node), "relay create"); err != nil {
-		logger.Log(1, "internal error when creating relay on node:", relay.NodeID)
-	}
-	go func() {
-		if err := mq.NodeUpdate(&node); err != nil {
-			logger.Log(1, "error publishing node update", err.Error())
-		}
-		if err := mq.PublishPeerUpdate(&node); err != nil {
-			logger.Log(1, "error publishing peer update ", err.Error())
-		}
-	}()
 	logger.Log(1, r.Header.Get("user"), "created relay on node", relay.NodeID, "on network", relay.NetID)
 	logger.Log(1, r.Header.Get("user"), "created relay on node", relay.NodeID, "on network", relay.NetID)
 	w.WriteHeader(http.StatusOK)
 	w.WriteHeader(http.StatusOK)
 	json.NewEncoder(w).Encode(node)
 	json.NewEncoder(w).Encode(node)
+	runUpdates(&node, true)
 }
 }
 
 
 func deleteRelay(w http.ResponseWriter, r *http.Request) {
 func deleteRelay(w http.ResponseWriter, r *http.Request) {
@@ -53,18 +42,8 @@ func deleteRelay(w http.ResponseWriter, r *http.Request) {
 		returnErrorResponse(w, r, formatError(err, "internal"))
 		returnErrorResponse(w, r, formatError(err, "internal"))
 		return
 		return
 	}
 	}
-	if err = runServerPeerUpdate(netid, isServer(&node), "relay delete"); err != nil {
-		logger.Log(1, "internal error when deleting relay on node:", nodeid)
-	}
-	go func() {
-		if err := mq.NodeUpdate(&node); err != nil {
-			logger.Log(1, "error publishing node update", err.Error())
-		}
-		if err := mq.PublishPeerUpdate(&node); err != nil {
-			logger.Log(1, "error publishing peer update ", err.Error())
-		}
-	}()
 	logger.Log(1, r.Header.Get("user"), "deleted relay server", nodeid, "on network", netid)
 	logger.Log(1, r.Header.Get("user"), "deleted relay server", nodeid, "on network", netid)
 	w.WriteHeader(http.StatusOK)
 	w.WriteHeader(http.StatusOK)
 	json.NewEncoder(w).Encode(node)
 	json.NewEncoder(w).Encode(node)
+	runUpdates(&node, true)
 }
 }

+ 11 - 3
controllers/server_util.go

@@ -3,19 +3,27 @@ package controller
 import (
 import (
 	"github.com/gravitl/netmaker/logger"
 	"github.com/gravitl/netmaker/logger"
 	"github.com/gravitl/netmaker/logic"
 	"github.com/gravitl/netmaker/logic"
+	"github.com/gravitl/netmaker/models"
+	"github.com/gravitl/netmaker/mq"
 	"github.com/gravitl/netmaker/servercfg"
 	"github.com/gravitl/netmaker/servercfg"
 )
 )
 
 
-func runServerPeerUpdate(network string, ifaceDelta bool, function string) error {
-	logger.Log(0, "running server update from function", function)
+func runServerPeerUpdate(node *models.Node, ifaceDelta bool) error {
+
 	err := logic.TimerCheckpoint()
 	err := logic.TimerCheckpoint()
 	if err != nil {
 	if err != nil {
 		logger.Log(3, "error occurred on timer,", err.Error())
 		logger.Log(3, "error occurred on timer,", err.Error())
 	}
 	}
+	if servercfg.IsMessageQueueBackend() {
+		if err := mq.PublishPeerUpdate(node); err != nil {
+			logger.Log(0, "failed to inform peers of new node ", err.Error())
+		}
+	}
+
 	if servercfg.IsClientMode() != "on" {
 	if servercfg.IsClientMode() != "on" {
 		return nil
 		return nil
 	}
 	}
-	var currentServerNodeID, getErr = logic.GetNetworkServerNodeID(network)
+	var currentServerNodeID, getErr = logic.GetNetworkServerNodeID(node.Network)
 	if err != nil {
 	if err != nil {
 		return getErr
 		return getErr
 	}
 	}

+ 38 - 0
logic/networks.go

@@ -1,6 +1,7 @@
 package logic
 package logic
 
 
 import (
 import (
+	"encoding/binary"
 	"encoding/json"
 	"encoding/json"
 	"errors"
 	"errors"
 	"fmt"
 	"fmt"
@@ -205,6 +206,43 @@ func UniqueAddress(networkName string) (string, error) {
 	return "W1R3: NO UNIQUE ADDRESSES AVAILABLE", err1
 	return "W1R3: NO UNIQUE ADDRESSES AVAILABLE", err1
 }
 }
 
 
+// UniqueAddressServer - get unique address starting from last available
+func UniqueAddressServer(networkName string) (string, error) {
+
+	var network models.Network
+	network, err := GetParentNetwork(networkName)
+	if err != nil {
+		logger.Log(0, "UniqueAddressServer encountered  an error")
+		return "666", err
+	}
+
+	_, ipv4Net, err := net.ParseCIDR(network.AddressRange)
+	if err != nil {
+		logger.Log(0, "UniqueAddressServer encountered  an error")
+		return "666", err
+	}
+
+	// convert IPNet struct mask and address to uint32
+	// network is BigEndian
+	mask := binary.BigEndian.Uint32(ipv4Net.Mask)
+	start := binary.BigEndian.Uint32(ipv4Net.IP)
+
+	// find the final address
+	finish := (start & mask) | (mask ^ 0xffffffff)
+
+	// loop through addresses as uint32
+	for i := finish - 1; i > start; i-- {
+		// convert back to net.IP
+		ip := make(net.IP, 4)
+		binary.BigEndian.PutUint32(ip, i)
+		if IsIPUnique(networkName, ip.String(), database.NODES_TABLE_NAME, false) && IsIPUnique(networkName, ip.String(), database.EXT_CLIENT_TABLE_NAME, false) {
+			return ip.String(), err
+		}
+	}
+
+	return "W1R3: NO UNIQUE ADDRESSES AVAILABLE", fmt.Errorf("no unique server addresses found")
+}
+
 // IsIPUnique - checks if an IP is unique
 // IsIPUnique - checks if an IP is unique
 func IsIPUnique(network string, ip string, tableName string, isIpv6 bool) bool {
 func IsIPUnique(network string, ip string, tableName string, isIpv6 bool) bool {
 
 

+ 32 - 6
logic/nodes.go

@@ -142,6 +142,12 @@ func UpdateNode(currentNode *models.Node, newNode *models.Node) error {
 		}
 		}
 	}
 	}
 	newNode.Fill(currentNode)
 	newNode.Fill(currentNode)
+
+	if currentNode.IsServer == "yes" && !validateServer(currentNode, newNode) {
+		return fmt.Errorf("this operation is not supported on server nodes")
+	}
+
+	// check for un-settable server values
 	if err := ValidateNode(newNode, true); err != nil {
 	if err := ValidateNode(newNode, true); err != nil {
 		return err
 		return err
 	}
 	}
@@ -208,14 +214,27 @@ func CreateNode(node *models.Node) error {
 			node.DNSOn = "no"
 			node.DNSOn = "no"
 		}
 		}
 	}
 	}
+
 	SetNodeDefaults(node)
 	SetNodeDefaults(node)
-	node.Address, err = UniqueAddress(node.Network)
-	if err != nil {
-		return err
+
+	if node.IsServer == "yes" {
+		if node.Address, err = UniqueAddressServer(node.Network); err != nil {
+			return err
+		}
+	} else if node.Address == "" {
+		if node.Address, err = UniqueAddress(node.Network); err != nil {
+			return err
+		}
+	} else if !IsIPUnique(node.Network, node.Address, database.NODES_TABLE_NAME, false) {
+		return fmt.Errorf("invalid address: ipv4 " + node.Address + " is not unique")
 	}
 	}
-	node.Address6, err = UniqueAddress6(node.Network)
-	if err != nil {
-		return err
+
+	if node.Address6 == "" {
+		if node.Address6, err = UniqueAddress6(node.Network); err != nil {
+			return err
+		}
+	} else if !IsIPUnique(node.Network, node.Address6, database.NODES_TABLE_NAME, true) {
+		return fmt.Errorf("invalid address: ipv6 " + node.Address6 + " is not unique")
 	}
 	}
 
 
 	// TODO: This covers legacy nodes, eventually want to remove legacy check
 	// TODO: This covers legacy nodes, eventually want to remove legacy check
@@ -609,3 +628,10 @@ func GetNetworkServerNodeID(network string) (string, error) {
 	}
 	}
 	return "", errors.New("could not find server node")
 	return "", errors.New("could not find server node")
 }
 }
+
+// validateServer - make sure servers dont change port or address
+func validateServer(currentNode, newNode *models.Node) bool {
+	return (newNode.Address == currentNode.Address &&
+		newNode.ListenPort == currentNode.ListenPort &&
+		newNode.IsServer == "yes")
+}

+ 20 - 18
logic/server.go

@@ -26,10 +26,10 @@ const KUBERNETES_LISTEN_PORT = 31821
 const KUBERNETES_SERVER_MTU = 1024
 const KUBERNETES_SERVER_MTU = 1024
 
 
 // ServerJoin - responsible for joining a server to a network
 // ServerJoin - responsible for joining a server to a network
-func ServerJoin(networkSettings *models.Network) error {
-
+func ServerJoin(networkSettings *models.Network) (models.Node, error) {
+	var returnNode models.Node
 	if networkSettings == nil || networkSettings.NetID == "" {
 	if networkSettings == nil || networkSettings.NetID == "" {
-		return errors.New("no network provided")
+		return returnNode, errors.New("no network provided")
 	}
 	}
 
 
 	var err error
 	var err error
@@ -70,7 +70,7 @@ func ServerJoin(networkSettings *models.Network) error {
 		}
 		}
 		if err != nil || node.Endpoint == "" {
 		if err != nil || node.Endpoint == "" {
 			logger.Log(0, "Error setting server node Endpoint.")
 			logger.Log(0, "Error setting server node Endpoint.")
-			return err
+			return returnNode, err
 		}
 		}
 	}
 	}
 
 
@@ -81,7 +81,7 @@ func ServerJoin(networkSettings *models.Network) error {
 		wgPrivatekey, err := wgtypes.GeneratePrivateKey()
 		wgPrivatekey, err := wgtypes.GeneratePrivateKey()
 		if err != nil {
 		if err != nil {
 			logger.Log(1, err.Error())
 			logger.Log(1, err.Error())
-			return err
+			return returnNode, err
 		}
 		}
 		privateKey = wgPrivatekey.String()
 		privateKey = wgPrivatekey.String()
 		node.PublicKey = wgPrivatekey.PublicKey().String()
 		node.PublicKey = wgPrivatekey.PublicKey().String()
@@ -90,13 +90,12 @@ func ServerJoin(networkSettings *models.Network) error {
 	node.Network = networkSettings.NetID
 	node.Network = networkSettings.NetID
 
 
 	logger.Log(2, "adding a server instance on network", node.Network)
 	logger.Log(2, "adding a server instance on network", node.Network)
-	err = CreateNode(node)
 	if err != nil {
 	if err != nil {
-		return err
+		return returnNode, err
 	}
 	}
 	err = SetNetworkNodesLastModified(node.Network)
 	err = SetNetworkNodesLastModified(node.Network)
 	if err != nil {
 	if err != nil {
-		return err
+		return returnNode, err
 	}
 	}
 
 
 	// get free port based on returned default listen port
 	// get free port based on returned default listen port
@@ -111,30 +110,30 @@ func ServerJoin(networkSettings *models.Network) error {
 	if node.IsLocal == "yes" && node.LocalRange != "" {
 	if node.IsLocal == "yes" && node.LocalRange != "" {
 		node.LocalAddress, err = ncutils.GetLocalIP(node.LocalRange)
 		node.LocalAddress, err = ncutils.GetLocalIP(node.LocalRange)
 		if err != nil {
 		if err != nil {
-			return err
+			return returnNode, err
 		}
 		}
 		node.Endpoint = node.LocalAddress
 		node.Endpoint = node.LocalAddress
 	}
 	}
 
 
-	if err = StorePrivKey(node.ID, privateKey); err != nil {
-		return err
+	if err = CreateNode(node); err != nil {
+		return returnNode, err
 	}
 	}
-	if err = serverPush(node); err != nil {
-		return err
+	if err = StorePrivKey(node.ID, privateKey); err != nil {
+		return returnNode, err
 	}
 	}
 
 
 	peers, hasGateway, gateways, err := GetServerPeers(node)
 	peers, hasGateway, gateways, err := GetServerPeers(node)
 	if err != nil && !ncutils.IsEmptyRecord(err) {
 	if err != nil && !ncutils.IsEmptyRecord(err) {
 		logger.Log(1, "failed to retrieve peers")
 		logger.Log(1, "failed to retrieve peers")
-		return err
+		return returnNode, err
 	}
 	}
 
 
 	err = initWireguard(node, privateKey, peers[:], hasGateway, gateways[:])
 	err = initWireguard(node, privateKey, peers[:], hasGateway, gateways[:])
 	if err != nil {
 	if err != nil {
-		return err
+		return returnNode, err
 	}
 	}
 
 
-	return nil
+	return *node, nil
 }
 }
 
 
 // ServerUpdate - updates the server
 // ServerUpdate - updates the server
@@ -143,8 +142,11 @@ func ServerUpdate(serverNode *models.Node, ifaceDelta bool) error {
 	var err = serverPull(serverNode, ifaceDelta)
 	var err = serverPull(serverNode, ifaceDelta)
 	if isDeleteError(err) {
 	if isDeleteError(err) {
 		return DeleteNodeByID(serverNode, true)
 		return DeleteNodeByID(serverNode, true)
-	} else if err != nil {
-		return err
+	} else if err != nil && !ifaceDelta {
+		err = serverPull(serverNode, true)
+		if err != nil {
+			return err
+		}
 	}
 	}
 
 
 	actionCompleted := checkNodeActions(serverNode)
 	actionCompleted := checkNodeActions(serverNode)

+ 11 - 0
logic/util.go

@@ -371,3 +371,14 @@ func setNetworkServerPeers(serverNode *models.Node) {
 		logger.Log(1, "could not set peers on network", serverNode.Network, ":", err.Error())
 		logger.Log(1, "could not set peers on network", serverNode.Network, ":", err.Error())
 	}
 	}
 }
 }
+
+// ShouldPublishPeerPorts - Gets ports from iface, sets, and returns true if they are different
+func ShouldPublishPeerPorts(serverNode *models.Node) bool {
+	if currentPeersList, err := getSystemPeers(serverNode); err == nil {
+		if database.SetPeers(currentPeersList, serverNode.Network) {
+			logger.Log(1, "set new peers on network", serverNode.Network)
+			return true
+		}
+	}
+	return false
+}

+ 4 - 0
main.go

@@ -39,6 +39,10 @@ func main() {
 func initialize() { // Client Mode Prereq Check
 func initialize() { // Client Mode Prereq Check
 	var err error
 	var err error
 
 
+	if servercfg.GetNodeID() == "" {
+		logger.FatalLog("error: must set NODE_ID, currently blank")
+	}
+
 	if err = database.InitializeDatabase(); err != nil {
 	if err = database.InitializeDatabase(); err != nil {
 		logger.FatalLog("Error connecting to database")
 		logger.FatalLog("Error connecting to database")
 	}
 	}

+ 22 - 3
mq/mq.go

@@ -15,6 +15,7 @@ import (
 	"github.com/gravitl/netmaker/logic"
 	"github.com/gravitl/netmaker/logic"
 	"github.com/gravitl/netmaker/models"
 	"github.com/gravitl/netmaker/models"
 	"github.com/gravitl/netmaker/servercfg"
 	"github.com/gravitl/netmaker/servercfg"
+	"github.com/gravitl/netmaker/serverctl"
 )
 )
 
 
 const KEEPALIVE_TIMEOUT = 60 //timeout in seconds
 const KEEPALIVE_TIMEOUT = 60 //timeout in seconds
@@ -106,9 +107,11 @@ func PublishPeerUpdate(newNode *models.Node) error {
 	}
 	}
 	for _, node := range networkNodes {
 	for _, node := range networkNodes {
 
 
-		if node.IsServer == "yes" {
+		if node.IsServer == "yes" || node.ID == newNode.ID {
+			log.Println("skipping update on " + node.Name + " : " + node.ID)
 			continue
 			continue
 		}
 		}
+		log.Println("running update on " + node.Name + " : " + node.ID)
 		peerUpdate, err := logic.GetPeerUpdate(&node)
 		peerUpdate, err := logic.GetPeerUpdate(&node)
 		if err != nil {
 		if err != nil {
 			logger.Log(1, "error getting peer update for node", node.ID, err.Error())
 			logger.Log(1, "error getting peer update for node", node.ID, err.Error())
@@ -122,7 +125,7 @@ func PublishPeerUpdate(newNode *models.Node) error {
 		if err = publish(&node, fmt.Sprintf("peers/%s/%s", node.Network, node.ID), data); err != nil {
 		if err = publish(&node, fmt.Sprintf("peers/%s/%s", node.Network, node.ID), data); err != nil {
 			logger.Log(1, "failed to publish peer update for node", node.ID)
 			logger.Log(1, "failed to publish peer update for node", node.ID)
 		} else {
 		} else {
-			logger.Log(1, fmt.Sprintf("sent peer update for network, %s and node, %s", node.Network, node.Name))
+			logger.Log(1, fmt.Sprintf("sent peer update for node %s on network: %s ", node.Name, node.Network))
 		}
 		}
 	}
 	}
 	return nil
 	return nil
@@ -198,6 +201,18 @@ func Keepalive(ctx context.Context) {
 						id = servAddr.ID
 						id = servAddr.ID
 					}
 					}
 				}
 				}
+				serverNode, errN := logic.GetNodeByID(id)
+				if errN == nil {
+					serverNode.SetLastCheckIn()
+					logic.UpdateNode(&serverNode, &serverNode)
+					if network.DefaultUDPHolePunch == "yes" {
+						logic.ShouldPublishPeerPorts(&serverNode)
+					}
+					err = PublishPeerUpdate(&serverNode)
+					if err != nil {
+						logger.Log(1, "error publishing udp port updates", err.Error())
+					}
+				}
 				if id == "" {
 				if id == "" {
 					logger.Log(0, "leader not defined for network", network.NetID)
 					logger.Log(0, "leader not defined for network", network.NetID)
 					continue
 					continue
@@ -207,8 +222,12 @@ func Keepalive(ctx context.Context) {
 				} else {
 				} else {
 					logger.Log(2, "keepalive sent for network", network.NetID)
 					logger.Log(2, "keepalive sent for network", network.NetID)
 				}
 				}
-				client.Disconnect(MQ_DISCONNECT)
+				err = serverctl.SyncServerNetwork(network.NetID)
+				if err != nil {
+					logger.Log(1, "error syncing server network", err.Error())
+				}
 			}
 			}
+			client.Disconnect(MQ_DISCONNECT)
 		}
 		}
 	}
 	}
 }
 }

+ 1 - 1
netclient/auth/auth.go

@@ -73,7 +73,7 @@ func AutoLogin(client nodepb.NodeServiceClient, network string) error {
 		return err
 		return err
 	}
 	}
 	tokenstring := []byte(res.Data)
 	tokenstring := []byte(res.Data)
-	err = os.WriteFile(home+"nettoken-"+network, tokenstring, 0600) // TODO: Proper permissions?
+	err = os.WriteFile(home+"nettoken-"+network, tokenstring, 0600)
 	if err != nil {
 	if err != nil {
 		return err
 		return err
 	}
 	}

+ 5 - 4
netclient/config/config.go

@@ -51,7 +51,7 @@ func Write(config *ClientConfig, network string) error {
 	}
 	}
 	_, err := os.Stat(ncutils.GetNetclientPath() + "/config")
 	_, err := os.Stat(ncutils.GetNetclientPath() + "/config")
 	if os.IsNotExist(err) {
 	if os.IsNotExist(err) {
-		os.MkdirAll(ncutils.GetNetclientPath()+"/config", 0744)
+		os.MkdirAll(ncutils.GetNetclientPath()+"/config", 0700)
 	} else if err != nil {
 	} else if err != nil {
 		return err
 		return err
 	}
 	}
@@ -77,9 +77,10 @@ func (config *ClientConfig) ReadConfig() {
 	nofile := false
 	nofile := false
 	//home, err := homedir.Dir()
 	//home, err := homedir.Dir()
 	home := ncutils.GetNetclientPathSpecific()
 	home := ncutils.GetNetclientPathSpecific()
+
 	file := fmt.Sprintf(home + "netconfig-" + config.Network)
 	file := fmt.Sprintf(home + "netconfig-" + config.Network)
 	//f, err := os.Open(file)
 	//f, err := os.Open(file)
-	f, err := os.OpenFile(file, os.O_RDONLY, 0666)
+	f, err := os.OpenFile(file, os.O_RDONLY, 0600)
 	if err != nil {
 	if err != nil {
 		fmt.Println("trouble opening file")
 		fmt.Println("trouble opening file")
 		fmt.Println(err)
 		fmt.Println(err)
@@ -134,7 +135,7 @@ func SaveBackup(network string) error {
 			ncutils.Log("failed to read " + configPath + " to make a backup")
 			ncutils.Log("failed to read " + configPath + " to make a backup")
 			return err
 			return err
 		}
 		}
-		if err = os.WriteFile(backupPath, input, 0644); err != nil {
+		if err = os.WriteFile(backupPath, input, 0600); err != nil {
 			ncutils.Log("failed to copy backup to " + backupPath)
 			ncutils.Log("failed to copy backup to " + backupPath)
 			return err
 			return err
 		}
 		}
@@ -152,7 +153,7 @@ func ReplaceWithBackup(network string) error {
 			ncutils.Log("failed to read file " + backupPath + " to backup network: " + network)
 			ncutils.Log("failed to read file " + backupPath + " to backup network: " + network)
 			return err
 			return err
 		}
 		}
-		if err = os.WriteFile(configPath, input, 0644); err != nil {
+		if err = os.WriteFile(configPath, input, 0600); err != nil {
 			ncutils.Log("failed backup " + backupPath + " to " + configPath)
 			ncutils.Log("failed backup " + backupPath + " to " + configPath)
 			return err
 			return err
 		}
 		}

+ 8 - 2
netclient/daemon/systemd.go

@@ -42,11 +42,17 @@ func SetupSystemDDaemon(interval string) error {
 	}
 	}
 
 
 	systemservice := `[Unit]
 	systemservice := `[Unit]
-Description=Netclient message queue
+Description=Netclient Daemon
+Documentation=https://docs.netmaker.org https://k8s.netmaker.org
+After=network-online.target
+Wants=network-online.target systemd-networkd-wait-online.service
 
 
 [Service]
 [Service]
+User=root
 Type=simple
 Type=simple
-ExecStart=/usr/sbin/netclient daemon
+ExecStart=/sbin/netclient daemon
+Restart=on-failure
+RestartSec=15s
 
 
 [Install]
 [Install]
 WantedBy=multi-user.target
 WantedBy=multi-user.target

+ 1 - 1
netclient/daemon/windows.go

@@ -56,7 +56,7 @@ func writeServiceConfig() error {
 </service>
 </service>
 `, strings.Replace(ncutils.GetNetclientPathSpecific()+"netclient.exe", `\\`, `\`, -1))
 `, strings.Replace(ncutils.GetNetclientPathSpecific()+"netclient.exe", `\\`, `\`, -1))
 	if !ncutils.FileExists(serviceConfigPath) {
 	if !ncutils.FileExists(serviceConfigPath) {
-		err := os.WriteFile(serviceConfigPath, []byte(scriptString), 0644)
+		err := os.WriteFile(serviceConfigPath, []byte(scriptString), 0600)
 		if err != nil {
 		if err != nil {
 			return err
 			return err
 		}
 		}

+ 110 - 51
netclient/functions/daemon.go

@@ -5,7 +5,6 @@ import (
 	"encoding/json"
 	"encoding/json"
 	"errors"
 	"errors"
 	"fmt"
 	"fmt"
-	"log"
 	"os"
 	"os"
 	"os/signal"
 	"os/signal"
 	"runtime"
 	"runtime"
@@ -15,7 +14,6 @@ import (
 	"time"
 	"time"
 
 
 	mqtt "github.com/eclipse/paho.mqtt.golang"
 	mqtt "github.com/eclipse/paho.mqtt.golang"
-	"github.com/gravitl/netmaker/logger"
 	"github.com/gravitl/netmaker/models"
 	"github.com/gravitl/netmaker/models"
 	"github.com/gravitl/netmaker/netclient/auth"
 	"github.com/gravitl/netmaker/netclient/auth"
 	"github.com/gravitl/netmaker/netclient/config"
 	"github.com/gravitl/netmaker/netclient/config"
@@ -26,21 +24,25 @@ import (
 )
 )
 
 
 // ServerKeepalive  - stores time of last server keepalive message
 // ServerKeepalive  - stores time of last server keepalive message
-var keepalive = make(map[string]time.Time, 3)
-var messageCache = make(map[string]string, 20)
+var keepalive = new(sync.Map)
+var messageCache = new(sync.Map)
 
 
 const lastNodeUpdate = "lnu"
 const lastNodeUpdate = "lnu"
 const lastPeerUpdate = "lpu"
 const lastPeerUpdate = "lpu"
 
 
 func insert(network, which, cache string) {
 func insert(network, which, cache string) {
-	var mu sync.Mutex
-	mu.Lock()
-	defer mu.Unlock()
-	messageCache[fmt.Sprintf("%s%s", network, which)] = cache
+	// var mu sync.Mutex
+	// mu.Lock()
+	// defer mu.Unlock()
+	messageCache.Store(fmt.Sprintf("%s%s", network, which), cache)
 }
 }
 
 
 func read(network, which string) string {
 func read(network, which string) string {
-	return messageCache[fmt.Sprintf("%s%s", network, which)]
+	val, isok := messageCache.Load(fmt.Sprintf("%s%s", network, which))
+	if isok {
+		return fmt.Sprintf("%v", val)
+	}
+	return ""
 }
 }
 
 
 // Daemon runs netclient daemon from command line
 // Daemon runs netclient daemon from command line
@@ -67,19 +69,30 @@ func SetupMQTT(cfg *config.ClientConfig) mqtt.Client {
 	opts := mqtt.NewClientOptions()
 	opts := mqtt.NewClientOptions()
 	for _, server := range cfg.Node.NetworkSettings.DefaultServerAddrs {
 	for _, server := range cfg.Node.NetworkSettings.DefaultServerAddrs {
 		if server.Address != "" && server.IsLeader {
 		if server.Address != "" && server.IsLeader {
-			ncutils.Log(fmt.Sprintf("adding server (%s) to listen on network %s", server.Address, cfg.Node.Network))
+			// ncutils.Log(fmt.Sprintf("adding server (%s) to listen on network %s", server.Address, cfg.Node.Network))
 			opts.AddBroker(server.Address + ":1883")
 			opts.AddBroker(server.Address + ":1883")
 			break
 			break
 		}
 		}
 	}
 	}
 	opts.SetDefaultPublishHandler(All)
 	opts.SetDefaultPublishHandler(All)
 	client := mqtt.NewClient(opts)
 	client := mqtt.NewClient(opts)
-	tperiod := time.Now().Add(10 * time.Second)
+	tperiod := time.Now().Add(12 * time.Second)
 	for {
 	for {
+		//if after 12 seconds, try a gRPC pull on the last try
+		if time.Now().After(tperiod) {
+			ncutils.Log("running pull for " + cfg.Node.Network)
+			_, err := Pull(cfg.Node.Network, true)
+			if err != nil {
+				ncutils.Log("could not run pull, exiting " + cfg.Node.Network + " setup: " + err.Error())
+				return client
+			}
+			time.Sleep(2 * time.Second)
+		}
 		if token := client.Connect(); token.Wait() && token.Error() != nil {
 		if token := client.Connect(); token.Wait() && token.Error() != nil {
-			logger.Log(2, "unable to connect to broker, retrying ...")
+			ncutils.Log("unable to connect to broker, retrying ...")
 			if time.Now().After(tperiod) {
 			if time.Now().After(tperiod) {
-				log.Fatal(0, "could not connect to broker, exiting ...", token.Error())
+				ncutils.Log("could not connect to broker, exiting " + cfg.Node.Network + " setup: " + token.Error().Error())
+				return client
 			}
 			}
 		} else {
 		} else {
 			break
 			break
@@ -94,43 +107,66 @@ func MessageQueue(ctx context.Context, network string) {
 	ncutils.Log("netclient go routine started for " + network)
 	ncutils.Log("netclient go routine started for " + network)
 	var cfg config.ClientConfig
 	var cfg config.ClientConfig
 	cfg.Network = network
 	cfg.Network = network
+	ncutils.Log("pulling latest config for " + cfg.Network)
+	sleepTime := 2
+	for {
+		_, err := Pull(network, true)
+		if err == nil {
+			break
+		}
+		if sleepTime > 3600 {
+			sleepTime = 3600
+		}
+		ncutils.Log("failed to pull for network " + network)
+		ncutils.Log(fmt.Sprintf("waiting %d seconds to retry...", sleepTime))
+		time.Sleep(time.Second * time.Duration(sleepTime))
+		sleepTime = sleepTime * 2
+	}
+	time.Sleep(time.Second << 1)
 	cfg.ReadConfig()
 	cfg.ReadConfig()
-	ncutils.Log("daemon started for network:" + network)
+	ncutils.Log("daemon started for network: " + network)
 	client := SetupMQTT(&cfg)
 	client := SetupMQTT(&cfg)
 	if cfg.DebugOn {
 	if cfg.DebugOn {
 		if token := client.Subscribe("#", 0, nil); token.Wait() && token.Error() != nil {
 		if token := client.Subscribe("#", 0, nil); token.Wait() && token.Error() != nil {
-			log.Fatal(token.Error())
+			ncutils.Log(token.Error().Error())
+			return
 		}
 		}
 		ncutils.Log("subscribed to all topics for debugging purposes")
 		ncutils.Log("subscribed to all topics for debugging purposes")
 	}
 	}
 	if token := client.Subscribe(fmt.Sprintf("update/%s/%s", cfg.Node.Network, cfg.Node.ID), 0, mqtt.MessageHandler(NodeUpdate)); token.Wait() && token.Error() != nil {
 	if token := client.Subscribe(fmt.Sprintf("update/%s/%s", cfg.Node.Network, cfg.Node.ID), 0, mqtt.MessageHandler(NodeUpdate)); token.Wait() && token.Error() != nil {
-		log.Fatal(token.Error())
+		ncutils.Log(token.Error().Error())
+		return
 	}
 	}
 	if cfg.DebugOn {
 	if cfg.DebugOn {
 		ncutils.Log(fmt.Sprintf("subscribed to node updates for node %s update/%s/%s", cfg.Node.Name, cfg.Node.Network, cfg.Node.ID))
 		ncutils.Log(fmt.Sprintf("subscribed to node updates for node %s update/%s/%s", cfg.Node.Name, cfg.Node.Network, cfg.Node.ID))
 	}
 	}
 	if token := client.Subscribe(fmt.Sprintf("peers/%s/%s", cfg.Node.Network, cfg.Node.ID), 0, mqtt.MessageHandler(UpdatePeers)); token.Wait() && token.Error() != nil {
 	if token := client.Subscribe(fmt.Sprintf("peers/%s/%s", cfg.Node.Network, cfg.Node.ID), 0, mqtt.MessageHandler(UpdatePeers)); token.Wait() && token.Error() != nil {
-		log.Fatal(token.Error())
+		ncutils.Log(token.Error().Error())
+		return
 	}
 	}
 	if cfg.DebugOn {
 	if cfg.DebugOn {
 		ncutils.Log(fmt.Sprintf("subscribed to peer updates for node %s peers/%s/%s", cfg.Node.Name, cfg.Node.Network, cfg.Node.ID))
 		ncutils.Log(fmt.Sprintf("subscribed to peer updates for node %s peers/%s/%s", cfg.Node.Name, cfg.Node.Network, cfg.Node.ID))
 	}
 	}
 	var id string
 	var id string
+	var found bool
 	for _, server := range cfg.NetworkSettings.DefaultServerAddrs {
 	for _, server := range cfg.NetworkSettings.DefaultServerAddrs {
 		if server.IsLeader {
 		if server.IsLeader {
 			id = server.ID
 			id = server.ID
 		}
 		}
 		if server.Address != "" {
 		if server.Address != "" {
 			if token := client.Subscribe("serverkeepalive/"+id, 0, mqtt.MessageHandler(ServerKeepAlive)); token.Wait() && token.Error() != nil {
 			if token := client.Subscribe("serverkeepalive/"+id, 0, mqtt.MessageHandler(ServerKeepAlive)); token.Wait() && token.Error() != nil {
-				log.Fatal(token.Error())
+				ncutils.Log(token.Error().Error())
+				return
 			}
 			}
+			found = true
 			if cfg.DebugOn {
 			if cfg.DebugOn {
 				ncutils.Log("subscribed to server keepalives for server " + id)
 				ncutils.Log("subscribed to server keepalives for server " + id)
 			}
 			}
-		} else {
-			ncutils.Log("leader not defined for network" + cfg.Network)
 		}
 		}
 	}
 	}
+	if !found {
+		ncutils.Log("leader not defined for network " + cfg.Network)
+	}
 	defer client.Disconnect(250)
 	defer client.Disconnect(250)
 	go MonitorKeepalive(ctx, client, &cfg)
 	go MonitorKeepalive(ctx, client, &cfg)
 	go Checkin(ctx, &cfg, network)
 	go Checkin(ctx, &cfg, network)
@@ -191,7 +227,7 @@ func NodeUpdate(client mqtt.Client, msg mqtt.Message) {
 				ncutils.PrintLog("error deleting local instance: "+err.Error(), 1)
 				ncutils.PrintLog("error deleting local instance: "+err.Error(), 1)
 				return
 				return
 			}
 			}
-			if token := client.Unsubscribe("update/"+newNode.ID, "update/peers/"+newNode.ID); token.Wait() && token.Error() != nil {
+			if token := client.Unsubscribe(fmt.Sprintf("update/%s/%s", newNode.Network, newNode.ID), fmt.Sprintf("peers/%s/%s", newNode.Network, newNode.ID)); token.Wait() && token.Error() != nil {
 				ncutils.PrintLog("error unsubscribing during node deletion", 1)
 				ncutils.PrintLog("error unsubscribing during node deletion", 1)
 			}
 			}
 			return
 			return
@@ -219,20 +255,27 @@ func NodeUpdate(client mqtt.Client, msg mqtt.Message) {
 		}
 		}
 		if ifaceDelta {
 		if ifaceDelta {
 			ncutils.Log("applying WG conf to " + file)
 			ncutils.Log("applying WG conf to " + file)
-			err = wireguard.ApplyWGQuickConf(file)
+			err = wireguard.ApplyWGQuickConf(file, cfg.Node.Interface)
 			if err != nil {
 			if err != nil {
 				ncutils.Log("error restarting wg after node update " + err.Error())
 				ncutils.Log("error restarting wg after node update " + err.Error())
 				return
 				return
 			}
 			}
-		} else {
-			ncutils.Log("syncing conf to " + file)
-			err = wireguard.SyncWGQuickConf(cfg.Node.Interface, file)
-			if err != nil {
-				ncutils.Log("error syncing wg after peer update " + err.Error())
+			time.Sleep(time.Second >> 1)
+			if err = Resubscribe(client, &cfg); err != nil {
+				ncutils.Log("error resubscribing after interface change " + err.Error())
 				return
 				return
 			}
 			}
 		}
 		}
-
+		/*
+			else {
+				ncutils.Log("syncing conf to " + file)
+				err = wireguard.SyncWGQuickConf(cfg.Node.Interface, file)
+				if err != nil {
+					ncutils.Log("error syncing wg after peer update " + err.Error())
+					return
+				}
+			}
+		*/
 		//deal with DNS
 		//deal with DNS
 		if newNode.DNSOn == "yes" {
 		if newNode.DNSOn == "yes" {
 			ncutils.Log("setting up DNS")
 			ncutils.Log("setting up DNS")
@@ -249,7 +292,7 @@ func NodeUpdate(client mqtt.Client, msg mqtt.Message) {
 	}()
 	}()
 }
 }
 
 
-// UpdatePeers -- mqtt message handler for /update/peers/<NodeID> topic
+// UpdatePeers -- mqtt message handler for peers/<Network>/<NodeID> topic
 func UpdatePeers(client mqtt.Client, msg mqtt.Message) {
 func UpdatePeers(client mqtt.Client, msg mqtt.Message) {
 	go func() {
 	go func() {
 		var peerUpdate models.PeerUpdate
 		var peerUpdate models.PeerUpdate
@@ -276,18 +319,14 @@ func UpdatePeers(client mqtt.Client, msg mqtt.Message) {
 		ncutils.Log("update peer handler")
 		ncutils.Log("update peer handler")
 
 
 		file := ncutils.GetNetclientPathSpecific() + cfg.Node.Interface + ".conf"
 		file := ncutils.GetNetclientPathSpecific() + cfg.Node.Interface + ".conf"
-		var shouldReSub = shouldResub(cfg.Node.NetworkSettings.DefaultServerAddrs, peerUpdate.ServerAddrs)
-		if shouldReSub {
-			Resubscribe(client, &cfg)
-			cfg.Node.NetworkSettings.DefaultServerAddrs = peerUpdate.ServerAddrs
-		}
 		err = wireguard.UpdateWgPeers(file, peerUpdate.Peers)
 		err = wireguard.UpdateWgPeers(file, peerUpdate.Peers)
 		if err != nil {
 		if err != nil {
 			ncutils.Log("error updating wireguard peers" + err.Error())
 			ncutils.Log("error updating wireguard peers" + err.Error())
 			return
 			return
 		}
 		}
 		ncutils.Log("syncing conf to " + file)
 		ncutils.Log("syncing conf to " + file)
-		err = wireguard.SyncWGQuickConf(cfg.Node.Interface, file)
+		//err = wireguard.SyncWGQuickConf(cfg.Node.Interface, file)
+		err = wireguard.SetPeers(cfg.Node.Interface, cfg.Node.PersistentKeepalive, peerUpdate.Peers)
 		if err != nil {
 		if err != nil {
 			ncutils.Log("error syncing wg after peer update " + err.Error())
 			ncutils.Log("error syncing wg after peer update " + err.Error())
 			return
 			return
@@ -308,9 +347,20 @@ func MonitorKeepalive(ctx context.Context, client mqtt.Client, cfg *config.Clien
 		case <-ctx.Done():
 		case <-ctx.Done():
 			return
 			return
 		case <-time.After(time.Second * 150):
 		case <-time.After(time.Second * 150):
-			if time.Since(keepalive[id]) > time.Second*200 { // more than 3+ minutes
-				ncutils.Log("server keepalive not recieved in more than minutes, resubscribe to message queue")
-				Resubscribe(client, cfg)
+			var keepalivetime time.Time
+			keepaliveval, ok := keepalive.Load(id)
+			if ok {
+				keepalivetime = keepaliveval.(time.Time)
+			} else {
+				ncutils.Log("unable to parse timestamp " + keepalivetime.String())
+				continue
+			}
+			if time.Since(keepalivetime) > time.Second*200 { // more than 3+ minutes
+				ncutils.Log("server keepalive not recieved recently, resubscribe to message queue")
+				err := Resubscribe(client, cfg)
+				if err != nil {
+					ncutils.Log("closing " + err.Error())
+				}
 			}
 			}
 		}
 		}
 	}
 	}
@@ -318,12 +368,15 @@ func MonitorKeepalive(ctx context.Context, client mqtt.Client, cfg *config.Clien
 
 
 // ServerKeepAlive -- handler to react to keepalive messages published by server
 // ServerKeepAlive -- handler to react to keepalive messages published by server
 func ServerKeepAlive(client mqtt.Client, msg mqtt.Message) {
 func ServerKeepAlive(client mqtt.Client, msg mqtt.Message) {
+	// var mu sync.Mutex
+	// mu.Lock()
+	// defer mu.Unlock()
 	serverid, err := getID(msg.Topic())
 	serverid, err := getID(msg.Topic())
 	if err != nil {
 	if err != nil {
 		ncutils.Log("invalid ID in serverkeepalive topic")
 		ncutils.Log("invalid ID in serverkeepalive topic")
 	}
 	}
-	keepalive[serverid] = time.Now()
-	ncutils.Log("keepalive from server")
+	keepalive.Store(serverid, time.Now())
+	// ncutils.Log("keepalive from server")
 }
 }
 
 
 // Resubscribe --- handles resubscribing if needed
 // Resubscribe --- handles resubscribing if needed
@@ -332,31 +385,37 @@ func Resubscribe(client mqtt.Client, cfg *config.ClientConfig) error {
 		ncutils.Log("resubbing on network " + cfg.Node.Network)
 		ncutils.Log("resubbing on network " + cfg.Node.Network)
 		client.Disconnect(250)
 		client.Disconnect(250)
 		client = SetupMQTT(cfg)
 		client = SetupMQTT(cfg)
-		if token := client.Subscribe("update/"+cfg.Node.ID, 0, NodeUpdate); token.Wait() && token.Error() != nil {
-			log.Fatal(token.Error())
+		if token := client.Subscribe(fmt.Sprintf("update/%s/%s", cfg.Node.Network, cfg.Node.ID), 0, NodeUpdate); token.Wait() && token.Error() != nil {
+			ncutils.Log("error resubscribing to updates for " + cfg.Node.Network)
+			return token.Error()
 		}
 		}
 		if cfg.DebugOn {
 		if cfg.DebugOn {
 			ncutils.Log("subscribed to node updates for node " + cfg.Node.Name + " update/" + cfg.Node.ID)
 			ncutils.Log("subscribed to node updates for node " + cfg.Node.Name + " update/" + cfg.Node.ID)
 		}
 		}
-		if token := client.Subscribe("update/peers/"+cfg.Node.ID, 0, UpdatePeers); token.Wait() && token.Error() != nil {
-			log.Fatal(token.Error())
+		if token := client.Subscribe(fmt.Sprintf("peers/%s/%s", cfg.Node.Network, cfg.Node.ID), 0, UpdatePeers); token.Wait() && token.Error() != nil {
+			ncutils.Log("error resubscribing to peers for " + cfg.Node.Network)
+			return token.Error()
 		}
 		}
 		var id string
 		var id string
+		var found bool
 		for _, server := range cfg.NetworkSettings.DefaultServerAddrs {
 		for _, server := range cfg.NetworkSettings.DefaultServerAddrs {
 			if server.IsLeader {
 			if server.IsLeader {
 				id = server.ID
 				id = server.ID
 			}
 			}
 			if server.Address != "" {
 			if server.Address != "" {
 				if token := client.Subscribe("serverkeepalive/"+id, 0, mqtt.MessageHandler(ServerKeepAlive)); token.Wait() && token.Error() != nil {
 				if token := client.Subscribe("serverkeepalive/"+id, 0, mqtt.MessageHandler(ServerKeepAlive)); token.Wait() && token.Error() != nil {
-					log.Fatal(token.Error())
+					ncutils.Log("error resubscribing to serverkeepalive for " + cfg.Node.Network)
+					return token.Error()
 				}
 				}
+				found = true
 				if cfg.DebugOn {
 				if cfg.DebugOn {
 					ncutils.Log("subscribed to server keepalives for server " + id)
 					ncutils.Log("subscribed to server keepalives for server " + id)
 				}
 				}
-			} else {
-				ncutils.Log("leader not defined for network" + cfg.Network)
 			}
 			}
 		}
 		}
+		if !found {
+			ncutils.Log("leader not defined for network " + cfg.Network)
+		}
 		ncutils.Log("finished re subbing")
 		ncutils.Log("finished re subbing")
 		return nil
 		return nil
 	} else {
 	} else {
@@ -397,7 +456,7 @@ func Checkin(ctx context.Context, cfg *config.ClientConfig, network string) {
 			return
 			return
 			//delay should be configuraable -> use cfg.Node.NetworkSettings.DefaultCheckInInterval ??
 			//delay should be configuraable -> use cfg.Node.NetworkSettings.DefaultCheckInInterval ??
 		case <-time.After(time.Second * 60):
 		case <-time.After(time.Second * 60):
-			ncutils.Log("Checkin running")
+			// ncutils.Log("Checkin running")
 			//read latest config
 			//read latest config
 			cfg.ReadConfig()
 			cfg.ReadConfig()
 			if cfg.Node.Roaming == "yes" && cfg.Node.IsStatic != "yes" {
 			if cfg.Node.Roaming == "yes" && cfg.Node.IsStatic != "yes" {
@@ -431,7 +490,7 @@ func Checkin(ctx context.Context, cfg *config.ClientConfig, network string) {
 				}
 				}
 			}
 			}
 			Hello(cfg, network)
 			Hello(cfg, network)
-			ncutils.Log("Checkin complete")
+			// ncutils.Log("Checkin complete")
 		}
 		}
 	}
 	}
 }
 }
@@ -439,11 +498,11 @@ func Checkin(ctx context.Context, cfg *config.ClientConfig, network string) {
 // PublishNodeUpdates -- saves node and pushes changes to broker
 // PublishNodeUpdates -- saves node and pushes changes to broker
 func PublishNodeUpdate(cfg *config.ClientConfig) {
 func PublishNodeUpdate(cfg *config.ClientConfig) {
 	if err := config.Write(cfg, cfg.Network); err != nil {
 	if err := config.Write(cfg, cfg.Network); err != nil {
-		ncutils.Log("error saving configuration" + err.Error())
+		ncutils.Log("error saving configuration: " + err.Error())
 	}
 	}
 	data, err := json.Marshal(cfg.Node)
 	data, err := json.Marshal(cfg.Node)
 	if err != nil {
 	if err != nil {
-		ncutils.Log("error marshling node update " + err.Error())
+		ncutils.Log("error marshling node update: " + err.Error())
 	}
 	}
 	if err = publish(cfg, fmt.Sprintf("update/%s", cfg.Node.ID), data); err != nil {
 	if err = publish(cfg, fmt.Sprintf("update/%s", cfg.Node.ID), data); err != nil {
 		ncutils.Log(fmt.Sprintf("error publishing endpoint update, %v", err))
 		ncutils.Log(fmt.Sprintf("error publishing endpoint update, %v", err))

+ 2 - 1
netclient/functions/join.go

@@ -116,7 +116,6 @@ func JoinNetwork(cfg config.ClientConfig, privateKey string) error {
 			cfg.Node.DNSOn = "no"
 			cfg.Node.DNSOn = "no"
 		}
 		}
 	}
 	}
-
 	if ncutils.IsFreeBSD() {
 	if ncutils.IsFreeBSD() {
 		cfg.Node.UDPHolePunch = "no"
 		cfg.Node.UDPHolePunch = "no"
 	}
 	}
@@ -125,6 +124,8 @@ func JoinNetwork(cfg config.ClientConfig, privateKey string) error {
 	// differentiate between client/server here
 	// differentiate between client/server here
 	var node = models.Node{
 	var node = models.Node{
 		Password:            cfg.Node.Password,
 		Password:            cfg.Node.Password,
+		Address:             cfg.Node.Address,
+		Address6:            cfg.Node.Address6,
 		ID:                  cfg.Node.ID,
 		ID:                  cfg.Node.ID,
 		MacAddress:          cfg.Node.MacAddress,
 		MacAddress:          cfg.Node.MacAddress,
 		AccessKey:           cfg.Server.AccessKey,
 		AccessKey:           cfg.Server.AccessKey,

+ 19 - 6
netclient/ncutils/iface.go

@@ -1,13 +1,13 @@
 package ncutils
 package ncutils
 
 
-import "github.com/gravitl/netmaker/models"
+import (
+	"net"
+
+	"github.com/gravitl/netmaker/models"
+)
 
 
 func IfaceDelta(currentNode *models.Node, newNode *models.Node) bool {
 func IfaceDelta(currentNode *models.Node, newNode *models.Node) bool {
 	// single comparison statements
 	// single comparison statements
-	if currentNode.IsServer != "yes" {
-		return false
-	}
-
 	if newNode.Endpoint != currentNode.Endpoint ||
 	if newNode.Endpoint != currentNode.Endpoint ||
 		newNode.LocalAddress != currentNode.LocalAddress ||
 		newNode.LocalAddress != currentNode.LocalAddress ||
 		newNode.PublicKey != currentNode.PublicKey ||
 		newNode.PublicKey != currentNode.PublicKey ||
@@ -57,7 +57,6 @@ func IfaceDelta(currentNode *models.Node, newNode *models.Node) bool {
 			return true
 			return true
 		}
 		}
 	}
 	}
-
 	return false
 	return false
 }
 }
 
 
@@ -70,3 +69,17 @@ func StringSliceContains(slice []string, item string) bool {
 	}
 	}
 	return false
 	return false
 }
 }
+
+// IfaceExists - return true if you can find the iface
+func IfaceExists(ifacename string) bool {
+	localnets, err := net.Interfaces()
+	if err != nil {
+		return false
+	}
+	for _, localnet := range localnets {
+		if ifacename == localnet.Name {
+			return true
+		}
+	}
+	return false
+}

+ 1 - 1
netclient/ncutils/netclientutils.go

@@ -462,7 +462,7 @@ func GetSystemNetworks() ([]string, error) {
 		}
 		}
 		file := filepath.Base(file)
 		file := filepath.Base(file)
 		temp := strings.Split(file, "-")
 		temp := strings.Split(file, "-")
-		networks = append(networks, temp[1])
+		networks = append(networks, strings.Join(temp[1:], "-"))
 	}
 	}
 	return networks, nil
 	return networks, nil
 }
 }

+ 1 - 1
netclient/ncwindows/windows.go

@@ -28,7 +28,7 @@ func InitWindows() {
 				log.Println("failed to find netclient.exe")
 				log.Println("failed to find netclient.exe")
 				return
 				return
 			}
 			}
-			if err = os.WriteFile(ncutils.GetNetclientPathSpecific()+"netclient.exe", input, 0644); err != nil {
+			if err = os.WriteFile(ncutils.GetNetclientPathSpecific()+"netclient.exe", input, 0600); err != nil {
 				log.Println("failed to copy netclient.exe to", ncutils.GetNetclientPath())
 				log.Println("failed to copy netclient.exe to", ncutils.GetNetclientPath())
 				return
 				return
 			}
 			}

+ 1 - 1
netclient/wireguard/common.go

@@ -277,7 +277,7 @@ func ApplyConf(node models.Node, ifacename string, confPath string) error {
 	case "darwin":
 	case "darwin":
 		_ = ApplyMacOSConf(node, ifacename, confPath)
 		_ = ApplyMacOSConf(node, ifacename, confPath)
 	default:
 	default:
-		err = ApplyWGQuickConf(confPath)
+		err = ApplyWGQuickConf(confPath, ifacename)
 	}
 	}
 	return err
 	return err
 }
 }

+ 2 - 2
netclient/wireguard/mac.go

@@ -99,7 +99,7 @@ func addInterface(iface string) (string, error) {
 	realIface, err := ncutils.GetNewIface("/var/run/wireguard/")
 	realIface, err := ncutils.GetNewIface("/var/run/wireguard/")
 	if iface != "" && err == nil {
 	if iface != "" && err == nil {
 		ifacePath := "/var/run/wireguard/" + iface + ".name"
 		ifacePath := "/var/run/wireguard/" + iface + ".name"
-		err = os.WriteFile(ifacePath, []byte(realIface), 0644)
+		err = os.WriteFile(ifacePath, []byte(realIface), 0600)
 	}
 	}
 	return realIface, err
 	return realIface, err
 }
 }
@@ -210,7 +210,7 @@ func addRoute(addr string, iface string) error {
 // setConfig - sets configuration of the wireguard interface from the config file
 // setConfig - sets configuration of the wireguard interface from the config file
 func setConfig(realIface string, confPath string) error {
 func setConfig(realIface string, confPath string) error {
 	confString := getConfig(confPath)
 	confString := getConfig(confPath)
-	err := os.WriteFile(confPath+".tmp", []byte(confString), 0644)
+	err := os.WriteFile(confPath+".tmp", []byte(confString), 0600)
 	if err != nil {
 	if err != nil {
 		return err
 		return err
 	}
 	}

+ 7 - 10
netclient/wireguard/unix.go

@@ -52,20 +52,17 @@ func SetWGKeyConfig(network string, serveraddr string) error {
 }
 }
 
 
 // ApplyWGQuickConf - applies wg-quick commands if os supports
 // ApplyWGQuickConf - applies wg-quick commands if os supports
-func ApplyWGQuickConf(confPath string) error {
+func ApplyWGQuickConf(confPath string, ifacename string) error {
 	_, err := os.Stat(confPath)
 	_, err := os.Stat(confPath)
 	if err != nil {
 	if err != nil {
 		ncutils.Log(confPath + " does not exist " + err.Error())
 		ncutils.Log(confPath + " does not exist " + err.Error())
 		return err
 		return err
 	}
 	}
-	_, err = ncutils.RunCmd("wg-quick down "+confPath, true)
-	if err != nil {
-		ncutils.Log("err runing wg-quick down " + confPath + err.Error())
+	if ncutils.IfaceExists(ifacename) {
+		ncutils.RunCmd("wg-quick down "+confPath, true)
 	}
 	}
 	_, err = ncutils.RunCmd("wg-quick up "+confPath, true)
 	_, err = ncutils.RunCmd("wg-quick up "+confPath, true)
-	if err != nil {
-		ncutils.Log("err runing wg-quick up " + confPath + err.Error())
-	}
+
 	return err
 	return err
 }
 }
 
 
@@ -90,7 +87,7 @@ func SyncWGQuickConf(iface string, confPath string) error {
 	}
 	}
 	regex := regexp.MustCompile(".*Warning.*\n")
 	regex := regexp.MustCompile(".*Warning.*\n")
 	conf := regex.ReplaceAllString(confRaw, "")
 	conf := regex.ReplaceAllString(confRaw, "")
-	err = os.WriteFile(tmpConf, []byte(conf), 0644)
+	err = os.WriteFile(tmpConf, []byte(conf), 0600)
 	if err != nil {
 	if err != nil {
 		return err
 		return err
 	}
 	}
@@ -98,7 +95,7 @@ func SyncWGQuickConf(iface string, confPath string) error {
 	if err != nil {
 	if err != nil {
 		log.Println(err.Error())
 		log.Println(err.Error())
 		ncutils.Log("error syncing conf, resetting")
 		ncutils.Log("error syncing conf, resetting")
-		err = ApplyWGQuickConf(confPath)
+		err = ApplyWGQuickConf(confPath, iface)
 	}
 	}
 	errN := os.Remove(tmpConf)
 	errN := os.Remove(tmpConf)
 	if errN != nil {
 	if errN != nil {
@@ -117,7 +114,7 @@ func RemoveWGQuickConf(confPath string, printlog bool) error {
 func StorePrivKey(key string, network string) error {
 func StorePrivKey(key string, network string) error {
 	var err error
 	var err error
 	d1 := []byte(key)
 	d1 := []byte(key)
-	err = os.WriteFile(ncutils.GetNetclientPathSpecific()+"wgkey-"+network, d1, 0644)
+	err = os.WriteFile(ncutils.GetNetclientPathSpecific()+"wgkey-"+network, d1, 0600)
 	return err
 	return err
 }
 }
 
 

+ 1 - 1
servercfg/serverconf.go

@@ -538,7 +538,7 @@ func IsHostNetwork() bool {
 // GetNodeID - gets the node id
 // GetNodeID - gets the node id
 func GetNodeID() string {
 func GetNodeID() string {
 	var id string
 	var id string
-	id = getMacAddr()
+	// id = getMacAddr()
 	if os.Getenv("NODE_ID") != "" {
 	if os.Getenv("NODE_ID") != "" {
 		id = os.Getenv("NODE_ID")
 		id = os.Getenv("NODE_ID")
 	} else if config.Config.Server.NodeID != "" {
 	} else if config.Config.Server.NodeID != "" {

+ 32 - 20
serverctl/serverctl.go

@@ -8,7 +8,6 @@ import (
 
 
 	"github.com/gravitl/netmaker/logger"
 	"github.com/gravitl/netmaker/logger"
 	"github.com/gravitl/netmaker/logic"
 	"github.com/gravitl/netmaker/logic"
-	"github.com/gravitl/netmaker/models"
 	"github.com/gravitl/netmaker/netclient/ncutils"
 	"github.com/gravitl/netmaker/netclient/ncutils"
 )
 )
 
 
@@ -28,8 +27,8 @@ func InitServerNetclient() error {
 }
 }
 
 
 // SyncServerNetwork - ensures a wg interface and node exists for server
 // SyncServerNetwork - ensures a wg interface and node exists for server
-func SyncServerNetwork(serverNode *models.Node) error {
-	serverNetworkSettings, err := logic.GetNetwork(serverNode.Network)
+func SyncServerNetwork(network string) error {
+	serverNetworkSettings, err := logic.GetNetwork(network)
 	if err != nil {
 	if err != nil {
 		return err
 		return err
 	}
 	}
@@ -37,14 +36,23 @@ func SyncServerNetwork(serverNode *models.Node) error {
 	if err != nil {
 	if err != nil {
 		return err
 		return err
 	}
 	}
-	exists := false
+
+	ifaceExists := false
 	for _, localnet := range localnets {
 	for _, localnet := range localnets {
 		if serverNetworkSettings.DefaultInterface == localnet.Name {
 		if serverNetworkSettings.DefaultInterface == localnet.Name {
-			exists = true
+			ifaceExists = true
 		}
 		}
 	}
 	}
-	if !exists {
-		err := logic.ServerJoin(&serverNetworkSettings)
+
+	serverNodeID, err := logic.GetNetworkServerNodeID(network)
+	if !ifaceExists && (err == nil && serverNodeID != "") {
+		serverNode, err := logic.GetNodeByID(serverNodeID)
+		if err != nil {
+			return err
+		}
+		return logic.ServerUpdate(&serverNode, true)
+	} else if !ifaceExists {
+		_, err := logic.ServerJoin(&serverNetworkSettings)
 		if err != nil {
 		if err != nil {
 			if err == nil {
 			if err == nil {
 				err = errors.New("network add failed for " + serverNetworkSettings.NetID)
 				err = errors.New("network add failed for " + serverNetworkSettings.NetID)
@@ -54,22 +62,26 @@ func SyncServerNetwork(serverNode *models.Node) error {
 			}
 			}
 		}
 		}
 	}
 	}
-	for _, localnet := range localnets {
-		if strings.Contains(localnet.Name, "nm-") {
-			var exists = ""
-			if serverNetworkSettings.DefaultInterface == localnet.Name {
-				exists = serverNetworkSettings.NetID
-			}
-			if exists == "" {
-				err := logic.DeleteNodeByID(serverNode, true)
-				if err != nil {
-					if err == nil {
-						err = errors.New("network delete failed for " + exists)
+
+	// remove networks locally that do not exist in database
+	/*
+		for _, localnet := range localnets {
+			if strings.Contains(localnet.Name, "nm-") {
+				var exists = ""
+				if serverNetworkSettings.DefaultInterface == localnet.Name {
+					exists = serverNetworkSettings.NetID
+				}
+				if exists == "" {
+					err := logic.DeleteNodeByID(serverNode, true)
+					if err != nil {
+						if err == nil {
+							err = errors.New("network delete failed for " + exists)
+						}
+						logger.Log(1, "error removing network", exists, "during sync", err.Error())
 					}
 					}
-					logger.Log(1, "error removing network", exists, "during sync", err.Error())
 				}
 				}
 			}
 			}
 		}
 		}
-	}
+	*/
 	return nil
 	return nil
 }
 }