Browse Source

Merge pull request #1957 from gravitl/gra-991-local-connection

Gra 991 local connection
dcarns 2 years ago
parent
commit
5a5613dd6d

+ 0 - 2
cli/cmd/network/create.go

@@ -53,7 +53,6 @@ var networkCreateCmd = &cobra.Command{
 			if allowManualSignUp {
 				network.AllowManualSignUp = "yes"
 			}
-			network.LocalRange = localRange
 			network.DefaultExtClientDNS = defaultExtClientDNS
 			network.DefaultMTU = int32(defaultMTU)
 		}
@@ -74,7 +73,6 @@ func init() {
 	networkCreateCmd.Flags().StringVar(&defaultInterface, "interface", "", "Name of the network interface")
 	networkCreateCmd.Flags().StringVar(&defaultPostUp, "post_up", "", "Commands to run after server is up `;` separated")
 	networkCreateCmd.Flags().StringVar(&defaultPostDown, "post_down", "", "Commands to run after server is down `;` separated")
-	networkCreateCmd.Flags().StringVar(&localRange, "local_range", "", "Local CIDR range")
 	networkCreateCmd.Flags().StringVar(&defaultExtClientDNS, "ext_client_dns", "", "IPv4 address of DNS server to be used by external clients")
 	networkCreateCmd.Flags().IntVar(&defaultListenPort, "listen_port", 51821, "Default wireguard port each node will attempt to use")
 	networkCreateCmd.Flags().IntVar(&nodeLimit, "node_limit", 999999999, "Maximum number of nodes that can be associated with this network")

+ 0 - 1
cli/cmd/network/flags.go

@@ -16,7 +16,6 @@ var (
 	defaultPostDown           string
 	defaultKeepalive          int
 	allowManualSignUp         bool
-	localRange                string
 	defaultExtClientDNS       string
 	defaultMTU                int
 )

+ 0 - 2
cli/cmd/network/update.go

@@ -56,7 +56,6 @@ var networkUpdateCmd = &cobra.Command{
 			if allowManualSignUp {
 				network.AllowManualSignUp = "yes"
 			}
-			network.LocalRange = localRange
 			network.DefaultExtClientDNS = defaultExtClientDNS
 			network.DefaultMTU = int32(defaultMTU)
 		}
@@ -75,7 +74,6 @@ func init() {
 	networkUpdateCmd.Flags().StringVar(&defaultInterface, "interface", "", "Name of the network interface")
 	networkUpdateCmd.Flags().StringVar(&defaultPostUp, "post_up", "", "Commands to run after server is up `;` separated")
 	networkUpdateCmd.Flags().StringVar(&defaultPostDown, "post_down", "", "Commands to run after server is down `;` separated")
-	networkUpdateCmd.Flags().StringVar(&localRange, "local_range", "", "Local CIDR range")
 	networkUpdateCmd.Flags().StringVar(&defaultExtClientDNS, "ext_client_dns", "", "IPv4 address of DNS server to be used by external clients")
 	networkUpdateCmd.Flags().IntVar(&defaultListenPort, "listen_port", 0, "Default wireguard port each node will attempt to use")
 	networkUpdateCmd.Flags().IntVar(&nodeLimit, "node_limit", 0, "Maximum number of nodes that can be associated with this network")

+ 2 - 12
controllers/network.go

@@ -191,7 +191,7 @@ func updateNetwork(w http.ResponseWriter, r *http.Request) {
 		newNetwork.DefaultPostUp = network.DefaultPostUp
 	}
 
-	rangeupdate4, rangeupdate6, localrangeupdate, holepunchupdate, groupsDelta, userDelta, err := logic.UpdateNetwork(&network, &newNetwork)
+	rangeupdate4, rangeupdate6, holepunchupdate, groupsDelta, userDelta, err := logic.UpdateNetwork(&network, &newNetwork)
 	if err != nil {
 		logger.Log(0, r.Header.Get("user"), "failed to update network: ",
 			err.Error())
@@ -237,17 +237,7 @@ func updateNetwork(w http.ResponseWriter, r *http.Request) {
 			return
 		}
 	}
-	if localrangeupdate {
-		err = logic.UpdateNetworkLocalAddresses(network.NetID)
-		if err != nil {
-			logger.Log(0, r.Header.Get("user"),
-				fmt.Sprintf("failed to update network [%s] local addresses: %v",
-					network.NetID, err.Error()))
-			logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
-			return
-		}
-	}
-	if rangeupdate4 || rangeupdate6 || localrangeupdate || holepunchupdate {
+	if rangeupdate4 || rangeupdate6 || holepunchupdate {
 		nodes, err := logic.GetNetworkNodes(network.NetID)
 		if err != nil {
 			logger.Log(0, r.Header.Get("user"),

+ 0 - 8
controllers/network_test.go

@@ -271,14 +271,6 @@ func TestValidateNetwork(t *testing.T) {
 			},
 			errMessage: "Field validation for 'DefaultKeepalive' failed on the 'max' tag",
 		},
-		{
-			testname: "InvalidLocalRange",
-			network: models.Network{
-				NetID:      "skynet",
-				LocalRange: "192.168.0.1",
-			},
-			errMessage: "Field validation for 'LocalRange' failed on the 'cidr' tag",
-		},
 	}
 	for _, tc := range cases {
 		t.Run(tc.testname, func(t *testing.T) {

+ 3 - 0
controllers/node.go

@@ -581,6 +581,9 @@ func createNode(w http.ResponseWriter, r *http.Request) {
 	// consume password before hashing for mq client creation
 	hostPassword := data.Host.HostPass
 	data.Node.Server = servercfg.GetServer()
+	if !logic.HostExists(&data.Host) {
+		logic.CheckHostPorts(&data.Host)
+	}
 	if err := logic.CreateHost(&data.Host); err != nil {
 		if errors.Is(err, logic.ErrHostExists) {
 			logger.Log(3, "host exists .. no need to create")

+ 0 - 5
logic/accesskeys.go

@@ -40,10 +40,6 @@ func CreateAccessKey(accesskey models.AccessKey, network models.Network) (models
 			return models.AccessKey{}, errors.New("duplicate AccessKey Name")
 		}
 	}
-	privAddr := ""
-	if network.IsLocal != "" {
-		privAddr = network.LocalRange
-	}
 
 	netID := network.NetID
 
@@ -52,7 +48,6 @@ func CreateAccessKey(accesskey models.AccessKey, network models.Network) (models
 	accessToken.APIConnString = servercfg.GetAPIConnString()
 	accessToken.ClientConfig.Network = netID
 	accessToken.ClientConfig.Key = accesskey.Value
-	accessToken.ClientConfig.LocalRange = privAddr
 
 	tokenjson, err := json.Marshal(accessToken)
 	if err != nil {

+ 62 - 0
logic/host_test.go

@@ -0,0 +1,62 @@
+package logic
+
+import (
+	"net"
+	"testing"
+
+	"github.com/google/uuid"
+	"github.com/gravitl/netmaker/database"
+	"github.com/gravitl/netmaker/models"
+	"github.com/matryer/is"
+)
+
+func TestCheckPorts(t *testing.T) {
+	database.InitializeDatabase()
+	h := models.Host{
+		ID:              uuid.New(),
+		EndpointIP:      net.ParseIP("192.168.1.1"),
+		ListenPort:      51821,
+		ProxyListenPort: maxPort,
+	}
+	testHost := models.Host{
+		ID:              uuid.New(),
+		EndpointIP:      net.ParseIP("192.168.1.1"),
+		ListenPort:      51830,
+		ProxyListenPort: 51730,
+	}
+	CreateHost(&h)
+	t.Run("no change", func(t *testing.T) {
+		is := is.New(t)
+		CheckHostPorts(&testHost)
+		is.Equal(testHost.ListenPort, 51830)
+		is.Equal(testHost.ProxyListenPort, 51730)
+	})
+	t.Run("same listen port", func(t *testing.T) {
+		is := is.New(t)
+		testHost.ListenPort = 51821
+		CheckHostPorts(&testHost)
+		is.Equal(testHost.ListenPort, 51822)
+		is.Equal(testHost.ProxyListenPort, 51730)
+	})
+	t.Run("same proxy port", func(t *testing.T) {
+		is := is.New(t)
+		testHost.ProxyListenPort = 65535
+		CheckHostPorts(&testHost)
+		is.Equal(testHost.ListenPort, 51822)
+		is.Equal(testHost.ProxyListenPort, minPort)
+	})
+	t.Run("listenport equals proxy port", func(t *testing.T) {
+		is := is.New(t)
+		testHost.ListenPort = maxPort
+		CheckHostPorts(&testHost)
+		is.Equal(testHost.ListenPort, minPort)
+		is.Equal(testHost.ProxyListenPort, minPort+1)
+	})
+	t.Run("proxyport equals listenport", func(t *testing.T) {
+		is := is.New(t)
+		testHost.ProxyListenPort = 51821
+		CheckHostPorts(&testHost)
+		is.Equal(testHost.ListenPort, minPort)
+		is.Equal(testHost.ProxyListenPort, 51822)
+	})
+}

+ 47 - 4
logic/hosts.go

@@ -20,6 +20,11 @@ var (
 	ErrInvalidHostID error = errors.New("invalid host id")
 )
 
+const (
+	maxPort = 1<<16 - 1
+	minPort = 1025
+)
+
 // GetAllHosts - returns all hosts in flat list or error
 func GetAllHosts() ([]models.Host, error) {
 	currHostMap, err := GetHostsMap()
@@ -117,10 +122,6 @@ func UpdateHost(newHost, currentHost *models.Host) {
 		newHost.Name = currentHost.Name
 	}
 
-	if newHost.LocalRange.String() != currentHost.LocalRange.String() {
-		newHost.LocalRange = currentHost.LocalRange
-	}
-
 	if newHost.MTU == 0 {
 		newHost.MTU = currentHost.MTU
 	}
@@ -328,3 +329,45 @@ func GetRelatedHosts(hostID string) []models.Host {
 	}
 	return relatedHosts
 }
+
+// CheckHostPort checks host endpoints to ensures that hosts on the same server
+// with the same endpoint have different listen ports
+// in the case of 64535 hosts or more with same endpoint, ports will not be changed
+func CheckHostPorts(h *models.Host) {
+	portsInUse := make(map[int]bool)
+	hosts, err := GetAllHosts()
+	if err != nil {
+		return
+	}
+	for _, host := range hosts {
+		if host.ID == h.ID {
+			//skip self
+			continue
+		}
+		if !host.EndpointIP.Equal(h.EndpointIP) {
+			continue
+		}
+		portsInUse[host.ListenPort] = true
+		portsInUse[host.ProxyListenPort] = true
+	}
+	// iterate until port is not found or max iteration is reached
+	for i := 0; portsInUse[h.ListenPort] && i < maxPort-minPort+1; i++ {
+		updatePort(&h.ListenPort)
+	}
+	for i := 0; portsInUse[h.ProxyListenPort] && i < maxPort-minPort+1; i++ {
+		updatePort(&h.ProxyListenPort)
+	}
+}
+
+// HostExists - checks if given host already exists
+func HostExists(h *models.Host) bool {
+	_, err := GetHost(h.ID.String())
+	return (err != nil && !database.IsEmptyRecord(err)) || (err == nil)
+}
+
+func updatePort(p *int) {
+	*p++
+	if *p > maxPort {
+		*p = minPort
+	}
+}

+ 5 - 60
logic/networks.go

@@ -298,60 +298,6 @@ func UniqueAddress6(networkName string, reverse bool) (net.IP, error) {
 	return add, errors.New("ERROR: No unique IPv6 addresses available. Check network subnet")
 }
 
-// GetLocalIP - gets the local ip
-func GetLocalIP(node models.Node) string {
-	var local string
-	ifaces, err := net.Interfaces()
-	if err != nil {
-		return local
-	}
-	host, err := GetHost(node.HostID.String())
-	if err != nil {
-		return local
-	}
-	localrange := host.LocalRange
-	found := false
-	for _, i := range ifaces {
-		if i.Flags&net.FlagUp == 0 {
-			continue // interface down
-		}
-		if i.Flags&net.FlagLoopback != 0 {
-			continue // loopback interface
-		}
-		addrs, err := i.Addrs()
-		if err != nil {
-			return local
-		}
-		for _, addr := range addrs {
-			var ip net.IP
-			switch v := addr.(type) {
-			case *net.IPNet:
-				if !found {
-					ip = v.IP
-					local = ip.String()
-					if node.IsLocal {
-						found = localrange.Contains(ip)
-					} else {
-						found = true
-					}
-				}
-			case *net.IPAddr:
-				if !found {
-					ip = v.IP
-					local = ip.String()
-					if node.IsLocal {
-						found = localrange.Contains(ip)
-
-					} else {
-						found = true
-					}
-				}
-			}
-		}
-	}
-	return local
-}
-
 // UpdateNetworkLocalAddresses - updates network localaddresses
 func UpdateNetworkLocalAddresses(networkName string) error {
 
@@ -517,14 +463,13 @@ func IsNetworkNameUnique(network *models.Network) (bool, error) {
 }
 
 // UpdateNetwork - updates a network with another network's fields
-func UpdateNetwork(currentNetwork *models.Network, newNetwork *models.Network) (bool, bool, bool, bool, []string, []string, error) {
+func UpdateNetwork(currentNetwork *models.Network, newNetwork *models.Network) (bool, bool, bool, []string, []string, error) {
 	if err := ValidateNetwork(newNetwork, true); err != nil {
-		return false, false, false, false, nil, nil, err
+		return false, false, false, nil, nil, err
 	}
 	if newNetwork.NetID == currentNetwork.NetID {
 		hasrangeupdate4 := newNetwork.AddressRange != currentNetwork.AddressRange
 		hasrangeupdate6 := newNetwork.AddressRange6 != currentNetwork.AddressRange6
-		localrangeupdate := newNetwork.LocalRange != currentNetwork.LocalRange
 		hasholepunchupdate := newNetwork.DefaultUDPHolePunch != currentNetwork.DefaultUDPHolePunch
 		groupDelta := append(StringDifference(newNetwork.ProSettings.AllowedGroups, currentNetwork.ProSettings.AllowedGroups),
 			StringDifference(currentNetwork.ProSettings.AllowedGroups, newNetwork.ProSettings.AllowedGroups)...)
@@ -532,14 +477,14 @@ func UpdateNetwork(currentNetwork *models.Network, newNetwork *models.Network) (
 			StringDifference(currentNetwork.ProSettings.AllowedUsers, newNetwork.ProSettings.AllowedUsers)...)
 		data, err := json.Marshal(newNetwork)
 		if err != nil {
-			return false, false, false, false, nil, nil, err
+			return false, false, false, nil, nil, err
 		}
 		newNetwork.SetNetworkLastModified()
 		err = database.Insert(newNetwork.NetID, string(data), database.NETWORKS_TABLE_NAME)
-		return hasrangeupdate4, hasrangeupdate6, localrangeupdate, hasholepunchupdate, groupDelta, userDelta, err
+		return hasrangeupdate4, hasrangeupdate6, hasholepunchupdate, groupDelta, userDelta, err
 	}
 	// copy values
-	return false, false, false, false, nil, nil, errors.New("failed to update network " + newNetwork.NetID + ", cannot change netid.")
+	return false, false, false, nil, nil, errors.New("failed to update network " + newNetwork.NetID + ", cannot change netid.")
 }
 
 // GetNetwork - gets a network from database

+ 0 - 1
logic/peers.go

@@ -252,7 +252,6 @@ func GetProxyUpdateForHost(host *models.Host) (proxy_models.ProxyManagerPayload,
 			if err != nil {
 				continue
 			}
-
 			var currPeerConf proxy_models.PeerConf
 			var found bool
 			if currPeerConf, found = peerConfMap[peerHost.PublicKey.String()]; !found {

+ 2 - 3
models/accessToken.go

@@ -8,7 +8,6 @@ type AccessToken struct {
 
 // ClientConfig - the config of the client
 type ClientConfig struct {
-	Network    string `json:"network"`
-	Key        string `json:"key"`
-	LocalRange string `json:"localrange"`
+	Network string `json:"network"`
+	Key     string `json:"key"`
 }

+ 0 - 13
models/api_host.go

@@ -13,7 +13,6 @@ type ApiHost struct {
 	Debug            bool     `json:"debug"`
 	IsStatic         bool     `json:"isstatic"`
 	ListenPort       int      `json:"listenport"`
-	LocalRange       string   `json:"localrange"`
 	LocalListenPort  int      `json:"locallistenport"`
 	ProxyListenPort  int      `json:"proxy_listen_port"`
 	MTU              int      `json:"mtu" yaml:"mtu"`
@@ -50,10 +49,6 @@ func (h *Host) ConvertNMHostToAPI() *ApiHost {
 	}
 	a.IsStatic = h.IsStatic
 	a.ListenPort = h.ListenPort
-	a.LocalRange = h.LocalRange.String()
-	if isEmptyAddr(a.LocalRange) {
-		a.LocalRange = ""
-	}
 	a.MTU = h.MTU
 	a.MacAddress = h.MacAddress.String()
 	a.Name = h.Name
@@ -106,14 +101,6 @@ func (a *ApiHost) ConvertAPIHostToNMHost(currentHost *Host) *Host {
 	h.RelayedHosts = a.RelayedHosts
 	h.IsRelay = a.IsRelay
 	h.IsRelayed = a.IsRelayed
-	if len(a.LocalRange) > 0 {
-		_, localRange, err := net.ParseCIDR(a.LocalRange)
-		if err == nil {
-			h.LocalRange = *localRange
-		}
-	} else if !isEmptyAddr(currentHost.LocalRange.String()) {
-		h.LocalRange = currentHost.LocalRange
-	}
 	h.ProxyEnabled = a.ProxyEnabled
 	h.IsDefault = a.IsDefault
 

+ 0 - 2
models/host.go

@@ -24,8 +24,6 @@ type Host struct {
 	Interface        string           `json:"interface" yaml:"interface"`
 	Debug            bool             `json:"debug" yaml:"debug"`
 	ListenPort       int              `json:"listenport" yaml:"listenport"`
-	LocalAddress     net.IPNet        `json:"localaddress" yaml:"localaddress"`
-	LocalRange       net.IPNet        `json:"localrange" yaml:"localrange"`
 	PublicListenPort int              `json:"public_listen_port" yaml:"public_listen_port"`
 	ProxyListenPort  int              `json:"proxy_listen_port" yaml:"proxy_listen_port"`
 	MTU              int              `json:"mtu" yaml:"mtu"`

+ 1 - 2
models/network.go

@@ -7,7 +7,7 @@ import (
 )
 
 // Network Struct - contains info for a given unique network
-//At  some point, need to replace all instances of Name with something else like  Identifier
+// At  some point, need to replace all instances of Name with something else like  Identifier
 type Network struct {
 	AddressRange        string                `json:"addressrange" bson:"addressrange" validate:"omitempty,cidrv4"`
 	AddressRange6       string                `json:"addressrange6" bson:"addressrange6" validate:"omitempty,cidrv6"`
@@ -26,7 +26,6 @@ type Network struct {
 	IsIPv4              string                `json:"isipv4" bson:"isipv4" validate:"checkyesorno"`
 	IsIPv6              string                `json:"isipv6" bson:"isipv6" validate:"checkyesorno"`
 	IsPointToSite       string                `json:"ispointtosite" bson:"ispointtosite" validate:"checkyesorno"`
-	LocalRange          string                `json:"localrange" bson:"localrange" validate:"omitempty,cidr"`
 	DefaultUDPHolePunch string                `json:"defaultudpholepunch" bson:"defaultudpholepunch" validate:"checkyesorno"`
 	DefaultExtClientDNS string                `json:"defaultextclientdns" bson:"defaultextclientdns"`
 	DefaultMTU          int32                 `json:"defaultmtu" bson:"defaultmtu"`

+ 0 - 9
models/network_test.go

@@ -13,13 +13,4 @@ package models
 //		assert.Equal(t, "NetID is not editable", err.Error())
 //		t.Log(err, Range, local)
 //	})
-//	t.Run("LocalRange", func(t *testing.T) {
-//		var networkupdate models.Network
-//		//NetID needs to be set as it will be in updateNetwork
-//		networkupdate.NetID = "skynet"
-//		networkupdate.LocalRange = "192.168.0.1/24"
-//		Range, local, err := network.Update(&networkupdate)
-//		assert.Nil(t, err)
-//		t.Log(err, Range, local)
-//	})
 //}

+ 0 - 9
models/node.go

@@ -150,7 +150,6 @@ type LegacyNode struct {
 	IsServer        string      `json:"isserver" bson:"isserver" yaml:"isserver" validate:"checkyesorno"`
 	Action          string      `json:"action" bson:"action" yaml:"action"`
 	IsLocal         string      `json:"islocal" bson:"islocal" yaml:"islocal" validate:"checkyesorno"`
-	LocalRange      string      `json:"localrange" bson:"localrange" yaml:"localrange"`
 	IPForwarding    string      `json:"ipforwarding" bson:"ipforwarding" yaml:"ipforwarding" validate:"checkyesorno"`
 	OS              string      `json:"os" bson:"os" yaml:"os"`
 	MTU             int32       `json:"mtu" bson:"mtu" yaml:"mtu"`
@@ -495,13 +494,6 @@ func (ln *LegacyNode) ConvertToNewNode() (*Host, *Node) {
 		host.HostPass = ln.Password
 		host.Name = ln.Name
 		host.ListenPort = int(ln.ListenPort)
-		if _, cidr, err := net.ParseCIDR(ln.LocalAddress); err == nil {
-			host.LocalRange = *cidr
-		} else {
-			if _, cidr, err := net.ParseCIDR(ln.LocalRange); err == nil {
-				host.LocalRange = *cidr
-			}
-		}
 		host.ProxyListenPort = int(ln.ProxyListenPort)
 		host.MTU = int(ln.MTU)
 		host.PublicKey, _ = wgtypes.ParseKey(ln.PublicKey)
@@ -594,7 +586,6 @@ func (n *Node) Legacy(h *Host, s *ServerConfig, net *Network) *LegacyNode {
 	l.DNSOn = formatBool(n.DNSOn)
 	l.Action = n.Action
 	l.IsLocal = formatBool(n.IsLocal)
-	l.LocalRange = h.LocalRange.String()
 	l.IPForwarding = formatBool(h.IPForwarding)
 	l.OS = h.OS
 	l.MTU = int32(h.MTU)

+ 7 - 1
mq/handlers.go

@@ -141,7 +141,7 @@ func UpdateHost(client mqtt.Client, msg mqtt.Message) {
 			logger.Log(1, "error unmarshaling payload ", err.Error())
 			return
 		}
-		logger.Log(0, "recieved host update for host: ", id)
+		logger.Log(3, fmt.Sprintf("recieved host update: %+v\n", hostUpdate))
 		var sendPeerUpdate bool
 		switch hostUpdate.Action {
 		case models.UpdateHost:
@@ -168,6 +168,12 @@ func UpdateHost(client mqtt.Client, msg mqtt.Message) {
 				logger.Log(0, "failed to pulish peer update: ", err.Error())
 			}
 		}
+		if sendPeerUpdate {
+			err := PublishPeerUpdate()
+			if err != nil {
+				logger.Log(0, "failed to pulish peer update: ", err.Error())
+			}
+		}
 		// if servercfg.Is_EE && ifaceDelta {
 		// 	if err = logic.EnterpriseResetAllPeersFailovers(currentHost.ID.String(), currentHost.Network); err != nil {
 		// 		logger.Log(1, "failed to reset failover list during node update", currentHost.ID.String(), currentHost.Network)

+ 1 - 1
serverctl/serverctl.go

@@ -85,7 +85,7 @@ func setNetworkDefaults() error {
 			}
 		} else {
 			network.SetDefaults()
-			_, _, _, _, _, _, err = logic.UpdateNetwork(&network, &network)
+			_, _, _, _, _, err = logic.UpdateNetwork(&network, &network)
 			if err != nil {
 				logger.Log(0, "could not set defaults on network", network.NetID)
 			}

+ 0 - 6
swagger.yaml

@@ -291,9 +291,6 @@ definitions:
             ispointtosite:
                 type: string
                 x-go-name: IsPointToSite
-            localrange:
-                type: string
-                x-go-name: LocalRange
             netid:
                 type: string
                 x-go-name: NetID
@@ -432,9 +429,6 @@ definitions:
                 format: int32
                 type: integer
                 x-go-name: LocalListenPort
-            localrange:
-                type: string
-                x-go-name: LocalRange
             macaddress:
                 type: string
                 x-go-name: MacAddress