Browse Source

routes for different OSs should be handled, cleaned up apply conf

0xdcarns 3 years ago
parent
commit
a0ae603a42

+ 7 - 0
netclient/local/routes.go

@@ -7,6 +7,8 @@ import (
 	"golang.zx2c4.com/wireguard/wgctrl/wgtypes"
 )
 
+// TODO handle ipv6 in future
+
 // SetPeerRoutes - sets/removes ip routes for each peer on a network
 func SetPeerRoutes(iface, currentNodeAddr string, oldPeers map[string][]net.IPNet, newPeers []wgtypes.PeerConfig) {
 	// traverse through all recieved peers
@@ -55,3 +57,8 @@ func SetCurrentPeerRoutes(iface, currentAddr string, peers []wgtypes.Peer) {
 		}
 	}
 }
+
+// SetCIDRRoute - sets the CIDR route, used on join and restarts
+func SetCIDRRoute(iface, currentAddr string, cidr *net.IPNet) {
+	setCidr(iface, currentAddr, cidr)
+}

+ 5 - 0
netclient/local/routes_darwin.go

@@ -2,6 +2,7 @@ package local
 
 import (
 	"net"
+	"strings"
 
 	"github.com/gravitl/netmaker/netclient/ncutils"
 )
@@ -30,3 +31,7 @@ func deleteRoute(iface string, addr *net.IPNet, address string) error {
 	_, err = ncutils.RunCmd("route -q -n delete "+addr.String(), true)
 	return err
 }
+
+func setCidr(iface, address string, addr *net.IPNet) {
+	ncutils.RunCmd("route -q -n add -net "+addr.String()+" "+address, true)
+}

+ 4 - 0
netclient/local/routes_freebsd.go

@@ -17,3 +17,7 @@ func deleteRoute(iface string, addr *net.IPNet, address string) error {
 	_, err = ncutils.RunCmd("route delete -net "+addr.String()+" -interface "+iface, true)
 	return err
 }
+
+func setCidr(iface, address string, addr *net.IPNet) {
+	ncutils.RunCmd("route add -net "+addr.String()+" -interface "+iface, true)
+}

+ 4 - 0
netclient/local/routes_linux.go

@@ -20,3 +20,7 @@ func deleteRoute(iface string, addr *net.IPNet, address string) error {
 	_, err = ncutils.RunCmd(fmt.Sprintf("ip route del %s dev %s", addr.String(), iface), true)
 	return err
 }
+
+func setCidr(iface, address string, addr *net.IPNet) {
+	ncutils.RunCmd("ip -4 route add "+addr.String()+" dev "+iface, false)
+}

+ 6 - 0
netclient/local/routes_windows.go

@@ -20,3 +20,9 @@ func deleteRoute(iface string, addr *net.IPNet, address string) error {
 	_, err = ncutils.RunCmd("route delete "+addr.IP.String()+" mask "+addr.Mask.String()+" "+address, true)
 	return err
 }
+
+func setCidr(iface, address string, addr *net.IPNet) {
+	ncutils.RunCmd("route -p add "+addr.IP.String()+" mask "+addr.Mask.String()+" "+address, true)
+	time.Sleep(time.Second >> 2)
+	ncutils.RunCmd("route change "+addr.IP.String()+" mask "+addr.Mask.String()+" "+address, true)
+}

+ 40 - 48
netclient/wireguard/common.go

@@ -1,7 +1,7 @@
 package wireguard
 
 import (
-	"errors"
+	"fmt"
 	"log"
 	"net"
 	"runtime"
@@ -157,60 +157,52 @@ func InitWireguard(node *models.Node, privkey string, peers []wgtypes.PeerConfig
 
 	// spin up userspace / windows interface + apply the conf file
 	confPath := ncutils.GetNetclientPathSpecific() + ifacename + ".conf"
-	var deviceiface string
-	if ncutils.IsMac() {
+	var deviceiface = ifacename
+	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
 		}
 	}
-	if syncconf {
+	// ensure you clear any existing interface first
+	d, _ := wgclient.Device(deviceiface)
+	for d != nil && d.Name == deviceiface {
+		RemoveConf(ifacename, false) // remove interface first
+		time.Sleep(time.Second >> 2)
+		d, _ = wgclient.Device(deviceiface)
+	}
+
+	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 := false
+	for !strings.Contains(output, ifacename) && !(time.Now().After(starttime.Add(time.Second << 4))) {
+		output, _ = ncutils.RunCmd("wg", false)
+		err = ApplyConf(node, ifacename, confPath)
+		time.Sleep(time.Second)
+		ifaceReady = !strings.Contains(output, ifacename)
+	}
+	newDevice, devErr := wgclient.Device(deviceiface)
+	if !ifaceReady || devErr != nil {
+		return fmt.Errorf("could not reliably create interface, please check wg installation and retry")
+	}
+	ncutils.PrintLog("interface ready - netclient engage", 1)
+
+	if syncconf { // should never be called really.
 		err = SyncWGQuickConf(ifacename, confPath)
-	} else {
-		if !ncutils.IsMac() {
-			d, _ := wgclient.Device(deviceiface)
-			for d != nil && d.Name == deviceiface {
-				RemoveConf(ifacename, false) // remove interface first
-				time.Sleep(time.Second >> 2)
-				d, _ = wgclient.Device(deviceiface)
-			}
-		}
-		if !ncutils.IsWindows() {
-			err = ApplyConf(*node, ifacename, confPath)
-			if err != nil {
-				ncutils.PrintLog("failed to create wireguard interface", 1)
-				return err
-			}
+	}
+	currentPeers := newDevice.Peers
+	if len(currentPeers) == 0 { // if no peers currently, apply cidr
+		_, cidr, cidrErr := net.ParseCIDR(modcfg.NetworkSettings.AddressRange)
+		if cidrErr == nil {
+			local.SetCIDRRoute(ifacename, node.Address, cidr)
 		} else {
-			var output string
-			starttime := time.Now()
-			RemoveConf(ifacename, false)
-			time.Sleep(time.Second >> 2)
-			ncutils.PrintLog("waiting for interface...", 1)
-			for !strings.Contains(output, ifacename) && !(time.Now().After(starttime.Add(time.Duration(10) * time.Second))) {
-				output, _ = ncutils.RunCmd("wg", false)
-				err = ApplyConf(*node, ifacename, confPath)
-				time.Sleep(time.Second)
-			}
-			if !strings.Contains(output, ifacename) {
-				return errors.New("could not create wg interface for " + ifacename)
-			}
-			ip, mask, err := ncutils.GetNetworkIPMask(nodecfg.NetworkSettings.AddressRange)
-			if err != nil {
-				log.Println(err.Error())
-				return err
-			}
-			ncutils.RunCmd("route add "+ip+" mask "+mask+" "+node.Address, true)
-			time.Sleep(time.Second >> 2)
-			ncutils.RunCmd("route change "+ip+" mask "+mask+" "+node.Address, true)
+			ncutils.PrintLog("could not set cidr route properly: "+cidrErr.Error(), 1)
 		}
-	}
-
-	//extra network route setting
-	if ncutils.IsFreeBSD() {
-		_, _ = ncutils.RunCmd("route add -net "+nodecfg.NetworkSettings.AddressRange+" -interface "+ifacename, true)
-	} else if ncutils.IsLinux() {
-		_, _ = ncutils.RunCmd("ip -4 route add "+nodecfg.NetworkSettings.AddressRange+" dev "+ifacename, false)
+	} else { // if peers, apply each
+		local.SetCurrentPeerRoutes(ifacename, node.Address, currentPeers[:])
 	}
 
 	return err
@@ -272,7 +264,7 @@ func RemoveConf(iface string, printlog bool) error {
 }
 
 // ApplyConf - applys a conf on disk to WireGuard interface
-func ApplyConf(node models.Node, ifacename string, confPath string) error {
+func ApplyConf(node *models.Node, ifacename string, confPath string) error {
 	os := runtime.GOOS
 	var err error
 	switch os {

+ 2 - 2
netclient/wireguard/mac.go

@@ -13,7 +13,7 @@ import (
 )
 
 // WgQuickDownMac - bring down mac interface, remove routes, and run post-down commands
-func WgQuickDownMac(node models.Node, iface string) error {
+func WgQuickDownMac(node *models.Node, iface string) error {
 	if err := RemoveConfMac(iface); err != nil {
 		return err
 	}
@@ -34,7 +34,7 @@ func RemoveConfMac(iface string) error {
 }
 
 // WgQuickUpMac - bring up mac interface and set routes
-func WgQuickUpMac(node models.Node, iface string, confPath string) error {
+func WgQuickUpMac(node *models.Node, iface string, confPath string) error {
 	var err error
 	var realIface string
 	realIface, err = getRealIface(iface)

+ 1 - 1
netclient/wireguard/unix.go

@@ -73,7 +73,7 @@ func ApplyWGQuickConf(confPath string, ifacename string) error {
 }
 
 // ApplyMacOSConf - applies system commands similar to wg-quick using golang for MacOS
-func ApplyMacOSConf(node models.Node, ifacename string, confPath string) error {
+func ApplyMacOSConf(node *models.Node, ifacename string, confPath string) error {
 	var err error
 	_ = WgQuickDownMac(node, ifacename)
 	err = WgQuickUpMac(node, ifacename, confPath)