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

Gra 991 local connection
This commit is contained in:
dcarns 2023-01-22 20:08:54 -05:00 committed by GitHub
commit 5a5613dd6d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
20 changed files with 130 additions and 141 deletions

View file

@ -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")

View file

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

View file

@ -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")

View file

@ -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"),

View file

@ -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) {

View file

@ -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")

View file

@ -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
logic/host_test.go Normal file
View file

@ -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)
})
}

View file

@ -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
}
}

View file

@ -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

View file

@ -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 {

View file

@ -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"`
}

View file

@ -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

View file

@ -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"`

View file

@ -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"`

View file

@ -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)
// })
//}

View file

@ -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)

View file

@ -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)

View file

@ -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)
}

View file

@ -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