Browse Source

fixing mac stuff and dns testing

afeiszli 3 years ago
parent
commit
96535554f5

+ 9 - 1
controllers/node.go

@@ -556,10 +556,18 @@ func updateNode(w http.ResponseWriter, r *http.Request) {
 		return
 	}
 	if relayupdate {
-		logic.UpdateRelay(node.Network, node.RelayAddrs, newNode.RelayAddrs)
+		updatenodes := logic.UpdateRelay(node.Network, node.RelayAddrs, newNode.RelayAddrs)
 		if err = logic.NetworkNodesUpdatePullChanges(node.Network); err != nil {
 			logger.Log(1, "error setting relay updates:", err.Error())
 		}
+		if len(updatenodes) > 0 {
+			for _, relayedNode := range updatenodes {
+				err = mq.NodeUpdate(&relayedNode)
+				if err != nil {
+					logger.Log(1, "error sending update to relayed node ", relayedNode.Address, "on network", node.Network, ": ", err.Error())
+				}
+			}
+		}
 	}
 
 	if servercfg.IsDNSMode() {

+ 11 - 6
controllers/relay.go

@@ -22,17 +22,16 @@ func createRelay(w http.ResponseWriter, r *http.Request) {
 	}
 	relay.NetID = params["network"]
 	relay.NodeID = params["nodeid"]
-	node, err := logic.CreateRelay(relay)
+	updatenodes, node, err := logic.CreateRelay(relay)
 	if err != nil {
 		returnErrorResponse(w, r, formatError(err, "internal"))
 		return
 	}
 	logger.Log(1, r.Header.Get("user"), "created relay on node", relay.NodeID, "on network", relay.NetID)
-	relayedNodes, err := logic.GetNodesByAddress(relay.NetID, relay.RelayAddrs)
-	for _, node := range relayedNodes {
-		err = mq.NodeUpdate(&node)
+	for _, relayedNode := range updatenodes {
+		err = mq.NodeUpdate(&relayedNode)
 		if err != nil {
-			logger.Log(1, "error sending update to relayed node ", node.Address, "on network", relay.NetID, ": ", err.Error())
+			logger.Log(1, "error sending update to relayed node ", relayedNode.Address, "on network", relay.NetID, ": ", err.Error())
 		}
 	}
 	w.WriteHeader(http.StatusOK)
@@ -45,12 +44,18 @@ func deleteRelay(w http.ResponseWriter, r *http.Request) {
 	var params = mux.Vars(r)
 	nodeid := params["nodeid"]
 	netid := params["network"]
-	node, err := logic.DeleteRelay(netid, nodeid)
+	updatenodes, node, err := logic.DeleteRelay(netid, nodeid)
 	if err != nil {
 		returnErrorResponse(w, r, formatError(err, "internal"))
 		return
 	}
 	logger.Log(1, r.Header.Get("user"), "deleted relay server", nodeid, "on network", netid)
+	for _, relayedNode := range updatenodes {
+		err = mq.NodeUpdate(&relayedNode)
+		if err != nil {
+			logger.Log(1, "error sending update to relayed node ", relayedNode.Address, "on network", netid, ": ", err.Error())
+		}
+	}
 	w.WriteHeader(http.StatusOK)
 	json.NewEncoder(w).Encode(node)
 	runUpdates(&node, true)

+ 33 - 29
logic/relay.go

@@ -11,15 +11,17 @@ import (
 )
 
 // CreateRelay - creates a relay
-func CreateRelay(relay models.RelayRequest) (models.Node, error) {
+func CreateRelay(relay models.RelayRequest) ([]models.Node, models.Node, error) {
+	var returnnodes []models.Node
+
 	node, err := GetNodeByID(relay.NodeID)
 	if err != nil {
-		return models.Node{}, err
+		return returnnodes, models.Node{}, err
 	}
 
 	err = ValidateRelay(relay)
 	if err != nil {
-		return models.Node{}, err
+		return returnnodes, models.Node{}, err
 	}
 	node.IsRelay = "yes"
 	node.RelayAddrs = relay.RelayAddrs
@@ -28,32 +30,31 @@ func CreateRelay(relay models.RelayRequest) (models.Node, error) {
 	node.PullChanges = "yes"
 	nodeData, err := json.Marshal(&node)
 	if err != nil {
-		return node, err
+		return returnnodes, node, err
 	}
 	if err = database.Insert(node.ID, string(nodeData), database.NODES_TABLE_NAME); err != nil {
-		return models.Node{}, err
+		return returnnodes, models.Node{}, err
 	}
-	err = SetRelayedNodes("yes", node.Network, node.RelayAddrs)
+	returnnodes, err = SetRelayedNodes("yes", node.Network, node.RelayAddrs)
 	if err != nil {
-		return node, err
+		return returnnodes, node, err
 	}
-
 	if err = NetworkNodesUpdatePullChanges(node.Network); err != nil {
-		return models.Node{}, err
+		return returnnodes, models.Node{}, err
 	}
-	return node, nil
+	return returnnodes, node, nil
 }
 
 // SetRelayedNodes- set relayed nodes
-func SetRelayedNodes(yesOrno string, networkName string, addrs []string) error {
-
+func SetRelayedNodes(yesOrno string, networkName string, addrs []string) ([]models.Node, error) {
+	var returnnodes []models.Node
 	collections, err := database.FetchRecords(database.NODES_TABLE_NAME)
 	if err != nil {
-		return err
+		return returnnodes, err
 	}
 	network, err := GetNetworkSettings(networkName)
 	if err != nil {
-		return err
+		return returnnodes, err
 	}
 
 	for _, value := range collections {
@@ -61,7 +62,7 @@ func SetRelayedNodes(yesOrno string, networkName string, addrs []string) error {
 		var node models.Node
 		err := json.Unmarshal([]byte(value), &node)
 		if err != nil {
-			return err
+			return returnnodes, err
 		}
 		if node.Network == networkName && !(node.IsServer == "yes") {
 			for _, addr := range addrs {
@@ -74,14 +75,15 @@ func SetRelayedNodes(yesOrno string, networkName string, addrs []string) error {
 					}
 					data, err := json.Marshal(&node)
 					if err != nil {
-						return err
+						return returnnodes, err
 					}
 					database.Insert(node.ID, string(data), database.NODES_TABLE_NAME)
+					returnnodes = append(returnnodes, node)
 				}
 			}
 		}
 	}
-	return nil
+	return returnnodes, nil
 }
 
 // SetNodeIsRelayed - Sets IsRelayed to on or off for relay
@@ -128,28 +130,30 @@ func ValidateRelay(relay models.RelayRequest) error {
 }
 
 // UpdateRelay - updates a relay
-func UpdateRelay(network string, oldAddrs []string, newAddrs []string) {
+func UpdateRelay(network string, oldAddrs []string, newAddrs []string) []models.Node {
+	var returnnodes []models.Node
 	time.Sleep(time.Second / 4)
-	err := SetRelayedNodes("no", network, oldAddrs)
+	returnnodes, err := SetRelayedNodes("no", network, oldAddrs)
 	if err != nil {
 		logger.Log(1, err.Error())
 	}
-	err = SetRelayedNodes("yes", network, newAddrs)
+	returnnodes, err = SetRelayedNodes("yes", network, newAddrs)
 	if err != nil {
 		logger.Log(1, err.Error())
 	}
+	return returnnodes
 }
 
 // DeleteRelay - deletes a relay
-func DeleteRelay(network, nodeid string) (models.Node, error) {
-
+func DeleteRelay(network, nodeid string) ([]models.Node, models.Node, error) {
+	var returnnodes []models.Node
 	node, err := GetNodeByID(nodeid)
 	if err != nil {
-		return models.Node{}, err
+		return returnnodes, models.Node{}, err
 	}
-	err = SetRelayedNodes("no", node.Network, node.RelayAddrs)
+	_, err = SetRelayedNodes("no", node.Network, node.RelayAddrs)
 	if err != nil {
-		return node, err
+		return returnnodes, node, err
 	}
 
 	node.IsRelay = "no"
@@ -159,13 +163,13 @@ func DeleteRelay(network, nodeid string) (models.Node, error) {
 
 	data, err := json.Marshal(&node)
 	if err != nil {
-		return models.Node{}, err
+		return returnnodes, models.Node{}, err
 	}
 	if err = database.Insert(nodeid, string(data), database.NODES_TABLE_NAME); err != nil {
-		return models.Node{}, err
+		return returnnodes, models.Node{}, err
 	}
 	if err = NetworkNodesUpdatePullChanges(network); err != nil {
-		return models.Node{}, err
+		return returnnodes, models.Node{}, err
 	}
-	return node, nil
+	return returnnodes, node, nil
 }

+ 8 - 1
netclient/command/commands.go

@@ -110,7 +110,14 @@ func CheckIn(cfg config.ClientConfig) error {
 			}
 			err = functions.CheckConfig(*currConf)
 			if err != nil {
-				ncutils.PrintLog("error checking in for "+network+" network: "+err.Error(), 1)
+				if strings.Contains(err.Error(), "could not find iface") {
+					err = Pull(cfg)
+					if err != nil {
+						ncutils.PrintLog(err.Error(), 1)
+					}
+				} else {
+					ncutils.PrintLog("error checking in for "+network+" network: "+err.Error(), 1)
+				}
 			} else {
 				ncutils.PrintLog("checked in successfully for "+network, 1)
 			}

+ 4 - 3
netclient/daemon/macos.go

@@ -11,6 +11,7 @@ import (
 )
 
 const MAC_SERVICE_NAME = "com.gravitl.netclient"
+const MAC_EXEC_DIR = "/usr/local/bin/"
 
 // SetupMacDaemon - Creates a daemon service from the netclient under LaunchAgents for MacOS
 func SetupMacDaemon(interval string) error {
@@ -21,8 +22,8 @@ func SetupMacDaemon(interval string) error {
 	}
 	binarypath := dir + "/netclient"
 
-	if !ncutils.FileExists(EXEC_DIR + "netclient") {
-		err = ncutils.Copy(binarypath, EXEC_DIR+"netclient")
+	if !ncutils.FileExists(MAC_EXEC_DIR + "netclient") {
+		err = ncutils.Copy(binarypath, MAC_EXEC_DIR+"netclient")
 		if err != nil {
 			log.Println(err)
 			return err
@@ -52,7 +53,7 @@ func CleanupMac() {
 	}
 
 	os.RemoveAll(ncutils.GetNetclientPath())
-	os.Remove(EXEC_DIR + "netclient")
+	os.Remove(MAC_EXEC_DIR + "netclient")
 }
 
 func RestartLaunchD() {

+ 12 - 3
netclient/functions/common.go

@@ -189,12 +189,21 @@ func LeaveNetwork(network string) error {
 
 	wgClient, wgErr := wgctrl.New()
 	if wgErr == nil {
-		dev, devErr := wgClient.Device(cfg.Node.Interface)
+		removeIface := cfg.Node.Interface
+		if ncutils.IsMac() {
+			var macIface string
+			macIface, wgErr = local.GetMacIface(cfg.Node.Address)
+			if wgErr == nil && removeIface != "" {
+				removeIface = macIface
+			}
+			wgErr = nil
+		}
+		dev, devErr := wgClient.Device(removeIface)
 		if devErr == nil {
-			local.FlushPeerRoutes(cfg.Node.Interface, cfg.Node.Address, dev.Peers[:])
+			local.FlushPeerRoutes(removeIface, cfg.Node.Address, dev.Peers[:])
 			_, cidr, cidrErr := net.ParseCIDR(cfg.NetworkSettings.AddressRange)
 			if cidrErr == nil {
-				local.RemoveCIDRRoute(cfg.Node.Interface, cfg.Node.Address, cidr)
+				local.RemoveCIDRRoute(removeIface, cfg.Node.Address, cidr)
 			}
 		} else {
 			ncutils.PrintLog("could not flush peer routes when leaving network, "+cfg.Node.Network, 1)

+ 1 - 1
netclient/functions/daemon.go

@@ -308,7 +308,7 @@ func NodeUpdate(client mqtt.Client, msg mqtt.Message) {
 			if newNode.DNSOn == "yes" {
 				for _, server := range newNode.NetworkSettings.DefaultServerAddrs {
 					if server.IsLeader {
-						go local.SetDNSWithRetry(newNode.Interface, newNode.Network, server.Address)
+						go local.SetDNSWithRetry(newNode, server.Address)
 						break
 					}
 				}

+ 6 - 1
netclient/functions/join.go

@@ -239,7 +239,12 @@ func JoinNetwork(cfg config.ClientConfig, privateKey string) error {
 	if node.DNSOn == "yes" {
 		for _, server := range node.NetworkSettings.DefaultServerAddrs {
 			if server.IsLeader {
-				go local.SetDNSWithRetry(node.Interface, node.Network, server.Address)
+				go func() {
+					if !local.SetDNSWithRetry(node, server.Address) {
+						cfg.Node.DNSOn = "no"
+						PublishNodeUpdate(&cfg)
+					}
+				}()
 				break
 			}
 		}

+ 14 - 7
netclient/local/dns.go

@@ -11,22 +11,29 @@ import (
 	"log"
 	"os/exec"
 
+	"github.com/gravitl/netmaker/models"
 	"github.com/gravitl/netmaker/netclient/ncutils"
 )
 
 const DNS_UNREACHABLE_ERROR = "nameserver unreachable"
 
-func SetDNSWithRetry(iface, network, address string) {
+// SetDNSWithRetry - Attempt setting dns, if it fails return true (to reset dns)
+func SetDNSWithRetry(node models.Node, address string) bool {
 	var reachable bool
 	for counter := 0; !reachable && counter < 5; counter++ {
 		reachable = IsDNSReachable(address)
 		time.Sleep(time.Second << 1)
 	}
 	if !reachable {
-		ncutils.Log("not setting dns, server unreachable: " + address)
-	} else if err := UpdateDNS(iface, network, address); err != nil {
+		ncutils.Log("not setting dns (server unreachable), will try again later: " + address)
+		return true
+	} else if err := UpdateDNS(node.Interface, node.Network, address); err != nil {
 		ncutils.Log("error applying dns" + err.Error())
+		return false
+	} else if IsDNSWorking(node.Network, address) {
+		return true
 	}
+	return false
 }
 
 // SetDNS - sets the DNS of a local machine
@@ -53,6 +60,9 @@ func SetDNS(nameserver string) error {
 
 // UpdateDNS - updates local DNS of client
 func UpdateDNS(ifacename string, network string, nameserver string) error {
+	if !ncutils.IsLinux() {
+		return nil
+	}
 	if ifacename == "" {
 		return fmt.Errorf("cannot set dns: interface name is blank")
 	}
@@ -62,9 +72,6 @@ func UpdateDNS(ifacename string, network string, nameserver string) error {
 	if nameserver == "" {
 		return fmt.Errorf("cannot set dns: nameserver is blank")
 	}
-	if ncutils.IsWindows() {
-		return nil
-	}
 	if !IsDNSReachable(nameserver) {
 		return fmt.Errorf(DNS_UNREACHABLE_ERROR + " : " + nameserver + ":53")
 	}
@@ -113,7 +120,7 @@ func IsDNSReachable(nameserver string) bool {
 // IsDNSWorking - checks if record is returned by correct nameserver
 func IsDNSWorking(network string, nameserver string) bool {
 	var isworking bool
-	servers, err := net.LookupNS("netmaker" + "." + "network")
+	servers, err := net.LookupNS("netmaker" + "." + network)
 	if err != nil {
 		return isworking
 	}

+ 59 - 48
netclient/wireguard/common.go

@@ -51,20 +51,40 @@ func SetPeers(iface, currentNodeAddr string, keepalive int32, peers []wgtypes.Pe
 		ncutils.PrintLog("no peers pulled", 1)
 		return err
 	}
-	found := false
-	//if a current peer is not in the list of new peers (based on PublicKey) delete it
-	for _, currentPeer := range devicePeers {
-		oldPeerAllowedIps[currentPeer.PublicKey.String()] = currentPeer.AllowedIPs
-		for _, peer := range peers {
-			if peer.PublicKey == currentPeer.PublicKey {
-				found = true
+	for _, peer := range peers {
+
+		for _, currentPeer := range devicePeers {
+			if currentPeer.AllowedIPs[0].String() == peer.AllowedIPs[0].String() &&
+				currentPeer.PublicKey.String() != peer.PublicKey.String() {
+				_, err := ncutils.RunCmd("wg set "+iface+" peer "+currentPeer.PublicKey.String()+" remove", true)
+				if err != nil {
+					ncutils.PrintLog("error removing peer "+peer.Endpoint.String(), 1)
+				}
 			}
 		}
-		if !found {
-			_, err := ncutils.RunCmd("wg set "+iface+" peer "+currentPeer.PublicKey.String()+" remove", true)
-			if err != nil {
-				log.Println("error removing peer", currentPeer.Endpoint.String())
-			}
+		udpendpoint := peer.Endpoint.String()
+		var allowedips string
+		var iparr []string
+		for _, ipaddr := range peer.AllowedIPs {
+			iparr = append(iparr, ipaddr.String())
+		}
+		allowedips = strings.Join(iparr, ",")
+		keepAliveString := strconv.Itoa(int(keepalive))
+		if keepAliveString == "0" {
+			keepAliveString = "15"
+		}
+		if peer.Endpoint != nil {
+			_, err = ncutils.RunCmd("wg set "+iface+" peer "+peer.PublicKey.String()+
+				" endpoint "+udpendpoint+
+				" persistent-keepalive "+keepAliveString+
+				" allowed-ips "+allowedips, true)
+		} else {
+			_, err = ncutils.RunCmd("wg set "+iface+" peer "+peer.PublicKey.String()+
+				" persistent-keepalive "+keepAliveString+
+				" allowed-ips "+allowedips, true)
+		}
+		if err != nil {
+			ncutils.PrintLog("error setting peer"+peer.PublicKey.String(), 1)
 		}
 	}
 	//if a new peer is not in the list of existing peers, add it
@@ -88,36 +108,12 @@ func SetPeers(iface, currentNodeAddr string, keepalive int32, peers []wgtypes.Pe
 				}
 
 			}
+		}
+		if shouldDelete {
+			output, err := ncutils.RunCmd("wg set "+iface+" peer "+currentPeer.PublicKey.String()+" remove", true)
+			if err != nil {
 
-			if !found || replace {
-				udpendpoint := peer.Endpoint.String()
-				var allowedips string
-				var iparr []string
-				for _, ipaddr := range peer.AllowedIPs {
-					iparr = append(iparr, ipaddr.String())
-				}
-				allowedips = strings.Join(iparr, ",")
-				keepAliveString := strconv.Itoa(int(keepalive))
-				if peer.Endpoint != nil && keepalive > 0 {
-					_, err = ncutils.RunCmd("wg set "+iface+" peer "+peer.PublicKey.String()+
-						" endpoint "+udpendpoint+
-						" persistent-keepalive "+keepAliveString+
-						" allowed-ips "+allowedips, true)
-				} else if peer.Endpoint != nil && keepalive == 0 {
-					_, err = ncutils.RunCmd("wg set "+iface+" peer "+peer.PublicKey.String()+
-						" endpoint "+udpendpoint+
-						" allowed-ips "+allowedips, true)
-				} else if peer.Endpoint == nil && keepalive != 0 {
-					_, err = ncutils.RunCmd("wg set "+iface+" peer "+peer.PublicKey.String()+
-						" persistent-keepalive "+keepAliveString+
-						" allowed-ips "+allowedips, true)
-				} else {
-					_, err = ncutils.RunCmd("wg set "+iface+" peer "+peer.PublicKey.String()+
-						" allowed-ips "+allowedips, true)
-				}
-				if err != nil {
-					log.Println("error setting peer", peer.PublicKey.String())
-				}
+				ncutils.PrintLog(output+" - error removing peer "+currentPeer.PublicKey.String(), 1)
 			}
 		}
 	}
@@ -153,7 +149,7 @@ func InitWireguard(node *models.Node, privkey string, peers []wgtypes.PeerConfig
 	if err != nil {
 		log.Fatalf("failed to open client: %v", err)
 	}
-
+	log.Println("-2")
 	var ifacename string
 	if nodecfg.Interface != "" {
 		ifacename = nodecfg.Interface
@@ -172,7 +168,7 @@ func InitWireguard(node *models.Node, privkey string, peers []wgtypes.PeerConfig
 		ncutils.PrintLog("error writing wg conf file: "+err.Error(), 1)
 		return err
 	}
-
+	log.Println("-1")
 	// spin up userspace / windows interface + apply the conf file
 	confPath := ncutils.GetNetclientPathSpecific() + ifacename + ".conf"
 	var deviceiface = ifacename
@@ -182,25 +178,40 @@ func InitWireguard(node *models.Node, privkey string, peers []wgtypes.PeerConfig
 			deviceiface = ifacename
 		}
 	}
+	log.Println("0")
 	// ensure you clear any existing interface first
 	d, _ := wgclient.Device(deviceiface)
 	for d != nil && d.Name == deviceiface {
-		RemoveConf(ifacename, false) // remove interface first
+		log.Println("d==", d.Name)
+		log.Println("deviceiface==", deviceiface)
+		err = RemoveConf(deviceiface, false) // remove interface first
+		if strings.Contains(err.Error(), "does not exist") {
+			err = nil
+			break
+		}
 		time.Sleep(time.Second >> 2)
 		d, _ = wgclient.Device(deviceiface)
 	}
-
+	log.Println("1")
 	ApplyConf(node, deviceiface, confPath)          // Apply initially
 	ncutils.PrintLog("waiting for interface...", 1) // ensure interface is created
 	output, _ := ncutils.RunCmd("wg", false)
 	starttime := time.Now()
-	ifaceReady := strings.Contains(output, ifacename)
+	ifaceReady := strings.Contains(output, deviceiface)
 	for !ifaceReady && !(time.Now().After(starttime.Add(time.Second << 4))) {
+		log.Println("2")
+		if ncutils.IsMac() { // if node is Mac (Darwin) get the tunnel name first
+			deviceiface, err = local.GetMacIface(node.Address)
+			if err != nil || deviceiface == "" {
+				deviceiface = ifacename
+			}
+		}
 		output, _ = ncutils.RunCmd("wg", false)
-		err = ApplyConf(node, ifacename, confPath)
+		err = ApplyConf(node, deviceiface, confPath)
 		time.Sleep(time.Second)
-		ifaceReady = strings.Contains(output, ifacename)
+		ifaceReady = strings.Contains(output, deviceiface)
 	}
+	log.Println("3")
 	//wgclient does not work well on freebsd
 	if node.OS == "freebsd" {
 		if !ifaceReady {

+ 2 - 0
netclient/wireguard/mac.go

@@ -3,6 +3,7 @@ package wireguard
 import (
 	"bufio"
 	"errors"
+	"log"
 	"os"
 	"strconv"
 	"strings"
@@ -27,6 +28,7 @@ func WgQuickDownMac(node *models.Node, iface string) error {
 // RemoveConfMac - bring down mac interface and remove routes
 func RemoveConfMac(iface string) error {
 	realIface, err := getRealIface(iface)
+	log.Println("DELETE ME: attempting to remove " + realIface)
 	if realIface != "" {
 		err = deleteInterface(iface, realIface)
 	}