Browse Source

Merge pull request #1021 from gravitl/feature_v0.13.0_localport

Feature v0.13.0 localport
Matthew R Kasun 3 years ago
parent
commit
28a2973fd4

+ 7 - 0
logic/peers.go

@@ -79,6 +79,10 @@ func GetNodePeers(networkName, nodeid string, excludeRelayed bool, isP2S bool) (
 					}
 				}
 			}
+			// if udp hole punching is on, but port is still set to default (e.g. 51821), use the LocalListenPort
+			if node.UDPHolePunch == "yes" && node.IsStatic != "yes" && peer.ListenPort == node.ListenPort {
+				peer.ListenPort = node.LocalListenPort
+			}
 			if node.IsRelay == "yes" {
 				network, err := GetNetwork(networkName)
 				if err == nil {
@@ -205,6 +209,9 @@ func GetPeerUpdate(node *models.Node) (models.PeerUpdate, error) {
 			// set_local
 			if node.LocalAddress != peer.LocalAddress && peer.LocalAddress != "" {
 				peer.Endpoint = peer.LocalAddress
+				if peer.LocalListenPort != 0 {
+					peer.ListenPort = peer.LocalListenPort
+				}
 			} else {
 				continue
 			}

+ 1 - 0
logic/util.go

@@ -154,6 +154,7 @@ func setPeerInfo(node *models.Node) models.Node {
 	peer.Name = node.Name
 	peer.Network = node.Network
 	peer.LocalAddress = node.LocalAddress
+	peer.LocalListenPort = node.LocalListenPort
 	peer.ListenPort = node.ListenPort
 	peer.AllowedIPs = node.AllowedIPs
 	peer.UDPHolePunch = node.UDPHolePunch

+ 4 - 0
models/node.go

@@ -37,6 +37,7 @@ type Node struct {
 	Address             string   `json:"address" bson:"address" yaml:"address" validate:"omitempty,ipv4"`
 	Address6            string   `json:"address6" bson:"address6" yaml:"address6" validate:"omitempty,ipv6"`
 	LocalAddress        string   `json:"localaddress" bson:"localaddress" yaml:"localaddress" validate:"omitempty,ip"`
+	LocalListenPort     int32    `json:"locallistenport" bson:"locallistenport" yaml:"locallistenport" validate:"numeric,min=0,max=65535"`
 	Name                string   `json:"name" bson:"name" yaml:"name" validate:"omitempty,max=62,in_charset"`
 	NetworkSettings     Network  `json:"networksettings" bson:"networksettings" yaml:"networksettings" validate:"-"`
 	ListenPort          int32    `json:"listenport" bson:"listenport" yaml:"listenport" validate:"omitempty,numeric,min=1024,max=65535"`
@@ -268,6 +269,9 @@ func (newNode *Node) Fill(currentNode *Node) {
 	if newNode.ListenPort == 0 && newNode.IsStatic != "yes" {
 		newNode.ListenPort = currentNode.ListenPort
 	}
+	if newNode.LocalListenPort == 0 && newNode.IsStatic != "yes" {
+		newNode.LocalListenPort = currentNode.LocalListenPort
+	}
 	if newNode.PublicKey == "" && newNode.IsStatic != "yes" {
 		newNode.PublicKey = currentNode.PublicKey
 	}

+ 9 - 7
models/structs.go

@@ -122,6 +122,7 @@ type PeersResponse struct {
 	Address             string `json:"address" bson:"address"`
 	Address6            string `json:"address6" bson:"address6"`
 	LocalAddress        string `json:"localaddress" bson:"localaddress"`
+	LocalListenPort     int32  `json:"locallistenport" bson:"locallistenport"`
 	IsEgressGateway     string `json:"isegressgateway" bson:"isegressgateway"`
 	EgressGatewayRanges string `json:"egressgatewayrange" bson:"egressgatewayrange"`
 	ListenPort          int32  `json:"listenport" bson:"listenport"`
@@ -130,13 +131,14 @@ type PeersResponse struct {
 
 // ExtPeersResponse - ext peers response
 type ExtPeersResponse struct {
-	PublicKey    string `json:"publickey" bson:"publickey"`
-	Endpoint     string `json:"endpoint" bson:"endpoint"`
-	Address      string `json:"address" bson:"address"`
-	Address6     string `json:"address6" bson:"address6"`
-	LocalAddress string `json:"localaddress" bson:"localaddress"`
-	ListenPort   int32  `json:"listenport" bson:"listenport"`
-	KeepAlive    int32  `json:"persistentkeepalive" bson:"persistentkeepalive"`
+	PublicKey       string `json:"publickey" bson:"publickey"`
+	Endpoint        string `json:"endpoint" bson:"endpoint"`
+	Address         string `json:"address" bson:"address"`
+	Address6        string `json:"address6" bson:"address6"`
+	LocalAddress    string `json:"localaddress" bson:"localaddress"`
+	LocalListenPort int32  `json:"locallistenport" bson:"locallistenport"`
+	ListenPort      int32  `json:"listenport" bson:"listenport"`
+	KeepAlive       int32  `json:"persistentkeepalive" bson:"persistentkeepalive"`
 }
 
 // EgressGatewayRequest - egress gateway request

+ 3 - 1
netclient/functions/daemon.go

@@ -218,6 +218,7 @@ func setupMQTT(cfg *config.ClientConfig, server string, publish bool) mqtt.Clien
 	opts.SetConnectRetryInterval(time.Second << 2)
 	opts.SetKeepAlive(time.Minute >> 1)
 	opts.SetWriteTimeout(time.Minute)
+
 	opts.SetOnConnectHandler(func(client mqtt.Client) {
 		if !publish {
 			networks, err := ncutils.GetSystemNetworks()
@@ -243,8 +244,8 @@ func setupMQTT(cfg *config.ClientConfig, server string, publish bool) mqtt.Clien
 		}
 		logger.Log(0, "connection re-established with mqtt server")
 	})
-
 	client := mqtt.NewClient(opts)
+
 	tperiod := time.Now().Add(12 * time.Second)
 	for {
 		//if after 12 seconds, try a pull on the last try
@@ -258,6 +259,7 @@ func setupMQTT(cfg *config.ClientConfig, server string, publish bool) mqtt.Clien
 			time.Sleep(time.Second)
 		}
 		if token := client.Connect(); token.Wait() && token.Error() != nil {
+
 			logger.Log(0, "unable to connect to broker, retrying ...")
 			if time.Now().After(tperiod) {
 				logger.Log(0, "could not connect to broker, exiting ", cfg.Node.Network, " setup: ", token.Error().Error())

+ 3 - 0
netclient/functions/join.go

@@ -189,6 +189,9 @@ func JoinNetwork(cfg *config.ClientConfig, privateKey string) error {
 	if err := Register(cfg, privateKey); err != nil {
 		return err
 	}
+
+	_ = UpdateLocalListenPort(cfg)
+
 	if cfg.Daemon != "off" {
 		err = daemon.InstallDaemon(cfg)
 		if err != nil {

+ 63 - 0
netclient/functions/localport.go

@@ -0,0 +1,63 @@
+//go:build !freebsd
+// +build !freebsd
+
+package functions
+
+import (
+	"strconv"
+
+	"github.com/gravitl/netmaker/logger"
+	"github.com/gravitl/netmaker/netclient/config"
+	"github.com/gravitl/netmaker/netclient/local"
+	"github.com/gravitl/netmaker/netclient/ncutils"
+	"golang.zx2c4.com/wireguard/wgctrl"
+)
+
+// GetLocalListenPort - Gets the port running on the local interface
+func GetLocalListenPort(ifacename string) (int32, error) {
+	client, err := wgctrl.New()
+	if err != nil {
+		logger.Log(0, "failed to start wgctrl")
+		return 0, err
+	}
+	defer client.Close()
+	device, err := client.Device(ifacename)
+	if err != nil {
+		logger.Log(0, "failed to parse interface")
+		return 0, err
+	}
+	return int32(device.ListenPort), nil
+}
+
+// UpdateLocalListenPort - check local port, if different, mod config and publish
+func UpdateLocalListenPort(nodeCfg *config.ClientConfig) error {
+	var err error
+	ifacename := getRealIface(nodeCfg.Node.Interface, nodeCfg.Node.Address)
+	localPort, err := GetLocalListenPort(ifacename)
+	if err != nil {
+		logger.Log(1, "error encountered checking local listen port: ", err.Error())
+	} else if nodeCfg.Node.LocalListenPort != localPort && localPort != 0 {
+		logger.Log(1, "local port has changed from ", strconv.Itoa(int(nodeCfg.Node.LocalListenPort)), " to ", strconv.Itoa(int(localPort)))
+		nodeCfg.Node.LocalListenPort = localPort
+		err = config.ModConfig(&nodeCfg.Node)
+		if err != nil {
+			return err
+		}
+		if err := PublishNodeUpdate(nodeCfg); err != nil {
+			logger.Log(0, "could not publish local port change")
+		}
+	}
+	return err
+}
+
+func getRealIface(ifacename string, address string) string {
+	var deviceiface = ifacename
+	var err error
+	if ncutils.IsMac() { // if node is Mac (Darwin) get the tunnel name first
+		deviceiface, err = local.GetMacIface(address)
+		if err != nil || deviceiface == "" {
+			deviceiface = ifacename
+		}
+	}
+	return deviceiface
+}

+ 50 - 0
netclient/functions/localport_freebsd.go

@@ -0,0 +1,50 @@
+//go:build freebsd
+// +build freebsd
+
+package functions
+
+import (
+	"errors"
+	"strconv"
+	"strings"
+
+	"github.com/gravitl/netmaker/logger"
+	"github.com/gravitl/netmaker/netclient/config"
+	"github.com/gravitl/netmaker/netclient/ncutils"
+)
+
+// GetLocalListenPort - Gets the port running on the local interface
+func GetLocalListenPort(ifacename string) (int32, error) {
+	portstring, err := ncutils.RunCmd("wg show "+ifacename+" listen-port", false)
+	if err != nil {
+		return 0, err
+	}
+	portstring = strings.TrimSuffix(portstring, "\n")
+	i, err := strconv.ParseInt(portstring, 10, 32)
+	if err != nil {
+		return 0, err
+	} else if i == 0 {
+		return 0, errors.New("parsed port is unset or invalid")
+	}
+	return int32(i), nil
+}
+
+// UpdateLocalListenPort - check local port, if different, mod config and publish
+func UpdateLocalListenPort(nodeCfg *config.ClientConfig) error {
+	var err error
+	localPort, err := GetLocalListenPort(nodeCfg.Node.Interface)
+	if err != nil {
+		logger.Log(1, "error encountered checking local listen port: ", err.Error())
+	} else if nodeCfg.Node.LocalListenPort != localPort && localPort != 0 {
+		logger.Log(1, "local port has changed from ", strconv.Itoa(int(nodeCfg.Node.LocalListenPort)), " to ", strconv.Itoa(int(localPort)))
+		nodeCfg.Node.LocalListenPort = localPort
+		err = config.ModConfig(&nodeCfg.Node)
+		if err != nil {
+			return err
+		}
+		if err := PublishNodeUpdate(nodeCfg); err != nil {
+			logger.Log(0, "could not publish local port change")
+		}
+	}
+	return err
+}

+ 2 - 0
netclient/functions/mqhandlers.go

@@ -155,6 +155,7 @@ func NodeUpdate(client mqtt.Client, msg mqtt.Message) {
 		//			logger.Log(0, "error applying dns" + err.Error())
 		//		}
 	}
+	_ = UpdateLocalListenPort(&nodeCfg)
 }
 
 // UpdatePeers -- mqtt message handler for peers/<Network>/<NodeID> topic
@@ -213,6 +214,7 @@ func UpdatePeers(client mqtt.Client, msg mqtt.Message) {
 			return
 		}
 	}
+	_ = UpdateLocalListenPort(&cfg)
 }
 
 func setHostDNS(dns, iface string, windows bool) error {

+ 4 - 1
netclient/functions/mqpublish.go

@@ -60,6 +60,8 @@ func Checkin(ctx context.Context, wg *sync.WaitGroup) {
 							logger.Log(0, "could not publish local address change")
 						}
 					}
+					_ = UpdateLocalListenPort(&nodeCfg)
+
 				} else if nodeCfg.Node.IsLocal == "yes" && nodeCfg.Node.LocalRange != "" {
 					localIP, err := ncutils.GetLocalIP(nodeCfg.Node.LocalRange)
 					if err != nil {
@@ -96,6 +98,7 @@ func PublishNodeUpdate(nodeCfg *config.ClientConfig) error {
 	if err = publish(nodeCfg, fmt.Sprintf("update/%s", nodeCfg.Node.ID), data, 1); err != nil {
 		return err
 	}
+
 	logger.Log(0, "sent a node update to server for node", nodeCfg.Node.Name, ", ", nodeCfg.Node.ID)
 	return nil
 }
@@ -120,7 +123,6 @@ func publish(nodeCfg *config.ClientConfig, dest string, msg []byte, qos byte) er
 	if err != nil {
 		return err
 	}
-
 	serverPubKey, err := ncutils.ConvertBytesToKey(nodeCfg.Node.TrafficKeys.Server)
 	if err != nil {
 		return err
@@ -136,6 +138,7 @@ func publish(nodeCfg *config.ClientConfig, dest string, msg []byte, qos byte) er
 	if token := client.Publish(dest, qos, false, encrypted); token.Wait() && token.Error() != nil {
 		return token.Error()
 	}
+
 	return nil
 }
 

+ 6 - 8
netclient/wireguard/common.go

@@ -233,14 +233,12 @@ func SetWGConfig(network string, peerupdate bool) error {
 	if err != nil {
 		return err
 	}
-	if peerupdate && !ncutils.IsFreeBSD() && !(ncutils.IsLinux() && !ncutils.IsKernel()) {
-		var iface string
-		iface = nodecfg.Interface
-		if ncutils.IsMac() {
-			iface, err = local.GetMacIface(nodecfg.Address)
-			if err != nil {
-				return err
-			}
+	var iface string
+	iface = nodecfg.Interface
+	if ncutils.IsMac() {
+		iface, err = local.GetMacIface(nodecfg.Address)
+		if err != nil {
+			return err
 		}
 		err = SetPeers(iface, &nodecfg, []wgtypes.PeerConfig{})
 	} else if peerupdate {