NM-159: simplify auto assign gw logic (#3719)

* force update host dns field if node is acting as inet gw

* add old acl support checks

* move auto relay migration to pro pkg

* add check to avoid unsetting relayed node

* simplify auto assign gw logic

* send auto assign update on un relay

* set checking time to latest on updates

* fix HA auto Relay logic

* add relay node metrics to peer signal

* move auto relay peer check

* publish host peer update

* check and unset unrelayed auto peers

* use relay node mutex to avoid rac condition

* reset autorelayed peers on auto assign gw
This commit is contained in:
Abhishek K
2025-11-06 14:54:09 +04:00
committed by GitHub
parent fc20b38851
commit c643a50b67
14 changed files with 173 additions and 139 deletions

View File

@@ -95,7 +95,7 @@ func createGateway(w http.ResponseWriter, r *http.Request) {
if relayedNode.FailedOverBy != uuid.Nil {
go logic.ResetFailedOverPeer(&relayedNode)
}
if relayedNode.AutoRelayedBy != uuid.Nil {
if len(relayedNode.AutoRelayedPeers) > 0 {
go logic.ResetAutoRelayedPeer(&relayedNode)
}

View File

@@ -6,7 +6,6 @@ import (
"net/http"
"strings"
"github.com/google/uuid"
"github.com/gorilla/mux"
"github.com/gravitl/netmaker/database"
"github.com/gravitl/netmaker/logger"
@@ -642,7 +641,7 @@ func updateNode(w http.ResponseWriter, r *http.Request) {
newNode.RelayedBy = ""
}
}
if (currentNode.IsRelayed || currentNode.FailedOverBy != uuid.Nil) && newNode.AutoAssignGateway {
if (currentNode.IsRelayed) && newNode.AutoAssignGateway {
// if relayed remove it
if currentNode.IsRelayed {
relayNode, err := logic.GetNodeByID(currentNode.RelayedBy)
@@ -653,7 +652,12 @@ func updateNode(w http.ResponseWriter, r *http.Request) {
newNode.IsRelayed = false
newNode.RelayedBy = ""
}
if currentNode.FailedOverBy != uuid.Nil {
if len(currentNode.AutoRelayedPeers) > 0 {
logic.ResetAutoRelayedPeer(&currentNode)
}
}
if !currentNode.AutoAssignGateway && newNode.AutoAssignGateway {
if len(currentNode.AutoRelayedPeers) > 0 {
logic.ResetAutoRelayedPeer(&currentNode)
}
}
@@ -697,10 +701,14 @@ func updateNode(w http.ResponseWriter, r *http.Request) {
// if !newNode.Connected {
// mq.HostUpdate(&models.HostUpdate{Host: *host, Action: models.SignalPull})
// }
mq.PublishPeerUpdate(false)
if newNode.AutoAssignGateway {
allNodes, err := logic.GetAllNodes()
if err == nil {
mq.PublishSingleHostPeerUpdate(host, allNodes, nil, nil, false, nil)
}
if servercfg.IsPro && newNode.AutoAssignGateway {
mq.HostUpdate(&models.HostUpdate{Action: models.CheckAutoAssignGw, Host: *host, Node: *newNode})
}
mq.PublishPeerUpdate(false)
if servercfg.IsDNSMode() {
logic.SetDNS()
}

View File

@@ -374,7 +374,7 @@ func ValidateInetGwReq(inetNode models.Node, req models.InetNodeReq, update bool
if clientNode.FailedOverBy != uuid.Nil {
ResetFailedOverPeer(&clientNode)
}
if clientNode.AutoRelayedBy != uuid.Nil {
if len(clientNode.AutoRelayedPeers) > 0 {
ResetAutoRelayedPeer(&clientNode)
}

View File

@@ -345,7 +345,7 @@ func UpdateHostFromClient(newHost, currHost *models.Host) (sendPeerUpdate bool)
if node.FailedOverBy != uuid.Nil {
ResetFailedOverPeer(&node)
}
if node.AutoRelayedBy != uuid.Nil {
if len(node.AutoRelayedPeers) > 0 {
ResetAutoRelayedPeer(&node)
}
}

View File

@@ -282,7 +282,7 @@ func DeleteNode(node *models.Node, purge bool) error {
if node.FailedOverBy != uuid.Nil {
ResetFailedOverPeer(node)
}
if node.AutoRelayedBy != uuid.Nil {
if len(node.AutoRelayedPeers) > 0 {
ResetAutoRelayedPeer(node)
}
if node.IsRelay {

View File

@@ -277,7 +277,7 @@ func GetPeerUpdateForHost(network string, host *models.Host, allNodes []models.N
node.Mutex.Lock()
}
_, isFailOverPeer := node.FailOverPeers[peer.ID.String()]
_, isAutoRelayPeer := node.AutoRelayedPeers[peer.ID.String()]
peerAutoRelayID, isAutoRelayPeer := node.AutoRelayedPeers[peer.ID.String()]
if node.Mutex != nil {
node.Mutex.Unlock()
}
@@ -294,9 +294,9 @@ func GetPeerUpdateForHost(network string, host *models.Host, allNodes []models.N
}
}
}
if isAutoRelayPeer && peer.AutoRelayedBy.String() != node.ID.String() {
if isAutoRelayPeer && peerAutoRelayID != node.ID.String() {
// get relay host
autoRelayNode, err := GetNodeByID(peer.AutoRelayedBy.String())
autoRelayNode, err := GetNodeByID(peerAutoRelayID)
if err == nil {
relayHost, err := GetHost(autoRelayNode.HostID.String())
if err == nil {
@@ -345,26 +345,20 @@ func GetPeerUpdateForHost(network string, host *models.Host, allNodes []models.N
peer)
}
}
shouldCheckRelayed := true
if (node.AutoAssignGateway && peer.IsGw && node.RelayedBy != peer.ID.String()) ||
(peer.AutoAssignGateway && node.IsGw && peer.RelayedBy != node.ID.String()) {
shouldCheckRelayed = false
}
if shouldCheckRelayed {
if (node.IsRelayed && node.RelayedBy != peer.ID.String()) ||
(peer.IsRelayed && peer.RelayedBy != node.ID.String()) || isFailOverPeer || isAutoRelayPeer {
// if node is relayed and peer is not the relay, set remove to true
if _, ok := peerIndexMap[peerHost.PublicKey.String()]; ok {
continue
}
peerConfig.Remove = true
hostPeerUpdate.Peers = append(hostPeerUpdate.Peers, peerConfig)
peerIndexMap[peerHost.PublicKey.String()] = len(hostPeerUpdate.Peers) - 1
if (node.IsRelayed && node.RelayedBy != peer.ID.String()) ||
(peer.IsRelayed && peer.RelayedBy != node.ID.String()) || isFailOverPeer || isAutoRelayPeer {
// if node is relayed and peer is not the relay, set remove to true
if _, ok := peerIndexMap[peerHost.PublicKey.String()]; ok {
continue
}
if node.IsRelayed && node.RelayedBy == peer.ID.String() {
hostPeerUpdate = SetDefaultGwForRelayedUpdate(node, peer, hostPeerUpdate)
}
peerConfig.Remove = true
hostPeerUpdate.Peers = append(hostPeerUpdate.Peers, peerConfig)
peerIndexMap[peerHost.PublicKey.String()] = len(hostPeerUpdate.Peers) - 1
continue
}
if node.IsRelayed && node.RelayedBy == peer.ID.String() {
hostPeerUpdate = SetDefaultGwForRelayedUpdate(node, peer, hostPeerUpdate)
}
uselocal := false
@@ -401,15 +395,14 @@ func GetPeerUpdateForHost(network string, host *models.Host, allNodes []models.N
peerEndpoint = peerHost.EndpointIPv6
}
}
if (node.IsRelay && peer.RelayedBy == node.ID.String() && peer.InternetGwID == "") ||
(peer.AutoAssignGateway && node.IsGw) && !peer.IsStatic {
if node.IsRelay && peer.RelayedBy == node.ID.String() && peer.InternetGwID == "" && !peer.IsStatic {
// don't set endpoint on relayed peer
peerEndpoint = nil
}
if isFailOverPeer && peer.FailedOverBy == node.ID && !peer.IsStatic {
peerEndpoint = nil
}
if isAutoRelayPeer && peer.AutoRelayedBy == node.ID && !peer.IsStatic {
if isAutoRelayPeer && peerAutoRelayID == node.ID.String() && !peer.IsStatic {
peerEndpoint = nil
}

View File

@@ -142,7 +142,7 @@ func ValidateRelay(relay models.RelayRequest, update bool) error {
if relayedNode.FailedOverBy != uuid.Nil {
ResetFailedOverPeer(&relayedNode)
}
if relayedNode.AutoRelayedBy != uuid.Nil {
if len(relayedNode.AutoRelayedPeers) > 0 {
ResetAutoRelayedPeer(&relayedNode)
}
}
@@ -212,9 +212,6 @@ func RelayedAllowedIPs(peer, node *models.Node) []net.IPNet {
if err != nil {
continue
}
if relayedNode.AutoAssignGateway && node.IsGw {
continue
}
GetNodeEgressInfo(&relayedNode, eli, acls)
allowed := getRelayedAddresses(relayedNodeID)
if relayedNode.EgressDetails.IsEgressGateway {
@@ -247,9 +244,6 @@ func GetAllowedIpsForRelayed(relayed, relay *models.Node) (allowedIPs []net.IPNe
if peer.ID == relayed.ID || peer.ID == relay.ID {
continue
}
if relayed.AutoAssignGateway && peer.IsGw {
continue
}
if !IsPeerAllowed(*relayed, peer, true) {
continue
}

View File

@@ -446,20 +446,6 @@ func updateNodes() {
node.Tags = make(map[models.TagID]struct{})
logic.UpsertNode(&node)
}
// deprecate failover and initialise auto relay fields
if node.IsFailOver {
node.IsFailOver = false
node.FailOverPeers = make(map[string]struct{})
node.FailedOverBy = uuid.Nil
node.AutoRelayedPeers = make(map[string]struct{})
logic.UpsertNode(&node)
}
if node.FailedOverBy != uuid.Nil || len(node.FailOverPeers) > 0 {
node.FailOverPeers = make(map[string]struct{})
node.FailedOverBy = uuid.Nil
node.AutoRelayedPeers = make(map[string]struct{})
logic.UpsertNode(&node)
}
if node.IsIngressGateway {
host, err := logic.GetHost(node.HostID.String())
if err == nil {

View File

@@ -17,26 +17,26 @@ type ApiNodeStatus struct {
// ApiNode is a stripped down Node DTO that exposes only required fields to external systems
type ApiNode struct {
ID string `json:"id,omitempty" validate:"required,min=5,id_unique"`
HostID string `json:"hostid,omitempty" validate:"required,min=5,id_unique"`
Address string `json:"address" validate:"omitempty,cidrv4"`
Address6 string `json:"address6" validate:"omitempty,cidrv6"`
LocalAddress string `json:"localaddress" validate:"omitempty,cidr"`
AllowedIPs []string `json:"allowedips"`
LastModified int64 `json:"lastmodified" swaggertype:"primitive,integer" format:"int64"`
ExpirationDateTime int64 `json:"expdatetime" swaggertype:"primitive,integer" format:"int64"`
LastCheckIn int64 `json:"lastcheckin" swaggertype:"primitive,integer" format:"int64"`
LastPeerUpdate int64 `json:"lastpeerupdate" swaggertype:"primitive,integer" format:"int64"`
Network string `json:"network"`
NetworkRange string `json:"networkrange"`
NetworkRange6 string `json:"networkrange6"`
IsRelayed bool `json:"isrelayed"`
IsRelay bool `json:"isrelay"`
IsGw bool `json:"is_gw"`
IsAutoRelay bool `json:"is_auto_relay"`
AutoRelayedPeers map[string]struct{} `json:"auto_relayed_peers"`
AutoAssignGateway bool `json:"auto_assign_gw"`
AutoRelayedBy uuid.UUID `json:"auto_relayed_by"`
ID string `json:"id,omitempty" validate:"required,min=5,id_unique"`
HostID string `json:"hostid,omitempty" validate:"required,min=5,id_unique"`
Address string `json:"address" validate:"omitempty,cidrv4"`
Address6 string `json:"address6" validate:"omitempty,cidrv6"`
LocalAddress string `json:"localaddress" validate:"omitempty,cidr"`
AllowedIPs []string `json:"allowedips"`
LastModified int64 `json:"lastmodified" swaggertype:"primitive,integer" format:"int64"`
ExpirationDateTime int64 `json:"expdatetime" swaggertype:"primitive,integer" format:"int64"`
LastCheckIn int64 `json:"lastcheckin" swaggertype:"primitive,integer" format:"int64"`
LastPeerUpdate int64 `json:"lastpeerupdate" swaggertype:"primitive,integer" format:"int64"`
Network string `json:"network"`
NetworkRange string `json:"networkrange"`
NetworkRange6 string `json:"networkrange6"`
IsRelayed bool `json:"isrelayed"`
IsRelay bool `json:"isrelay"`
IsGw bool `json:"is_gw"`
IsAutoRelay bool `json:"is_auto_relay"`
AutoRelayedPeers map[string]string `json:"auto_relayed_peers"`
AutoAssignGateway bool `json:"auto_assign_gw"`
//AutoRelayedBy uuid.UUID `json:"auto_relayed_by"`
RelayedBy string `json:"relayedby" bson:"relayedby" yaml:"relayedby"`
RelayedNodes []string `json:"relaynodes" yaml:"relayedNodes"`
IsEgressGateway bool `json:"isegressgateway"`
@@ -79,6 +79,9 @@ func (a *ApiNode) ConvertToServerNode(currentNode *Node) *Node {
convertedNode.ID, _ = uuid.Parse(a.ID)
convertedNode.HostID, _ = uuid.Parse(a.HostID)
//convertedNode.IsRelay = a.IsRelay
if a.RelayedBy != "" && !a.IsRelayed {
a.IsRelayed = true
}
convertedNode.IsRelayed = a.IsRelayed
convertedNode.RelayedBy = a.RelayedBy
convertedNode.RelayedNodes = a.RelayedNodes
@@ -196,7 +199,7 @@ func (nm *Node) ConvertToAPINode() *ApiNode {
apiNode.RelayedBy = nm.RelayedBy
apiNode.RelayedNodes = nm.RelayedNodes
apiNode.IsAutoRelay = nm.IsAutoRelay
apiNode.AutoRelayedBy = nm.AutoRelayedBy
//apiNode.AutoRelayedBy = nm.AutoRelayedBy
apiNode.AutoRelayedPeers = nm.AutoRelayedPeers
apiNode.AutoAssignGateway = nm.AutoAssignGateway
apiNode.IsIngressGateway = nm.IsIngressGateway

View File

@@ -160,18 +160,19 @@ type HostTurnRegister struct {
// Signal - struct for signalling peer
type Signal struct {
Server string `json:"server"`
FromHostPubKey string `json:"from_host_pubkey"`
ToHostPubKey string `json:"to_host_pubkey"`
FromHostID string `json:"from_host_id"`
ToHostID string `json:"to_host_id"`
FromNodeID string `json:"from_node_id"`
ToNodeID string `json:"to_node_id"`
NetworkID string `json:"networkID"`
Reply bool `json:"reply"`
Action SignalAction `json:"action"`
IsPro bool `json:"is_pro"`
TimeStamp int64 `json:"timestamp"`
Server string `json:"server"`
FromHostPubKey string `json:"from_host_pubkey"`
ToHostPubKey string `json:"to_host_pubkey"`
FromHostID string `json:"from_host_id"`
ToHostID string `json:"to_host_id"`
FromNodeID string `json:"from_node_id"`
ToNodeID string `json:"to_node_id"`
NetworkID string `json:"networkID"`
Reply bool `json:"reply"`
AutoRelayNodeMetrics map[string]int64 `json:"auto_relay_node_metrics"`
Action SignalAction `json:"action"`
IsPro bool `json:"is_pro"`
TimeStamp int64 `json:"timestamp"`
}
// RegisterMsg - login message struct for hosts to join via SSO login

View File

@@ -106,12 +106,13 @@ type Node struct {
IngressMTU int32 `json:"ingressmtu"`
Metadata string `json:"metadata"`
// == PRO ==
DefaultACL string `json:"defaultacl,omitempty" validate:"checkyesornoorunset"`
OwnerID string `json:"ownerid,omitempty"`
IsFailOver bool `json:"is_fail_over"`
IsAutoRelay bool `json:"is_auto_relay"`
AutoRelayedPeers map[string]struct{} `json:"auto_relayed_peers"`
AutoRelayedBy uuid.UUID `json:"auto_relayed_by"`
DefaultACL string `json:"defaultacl,omitempty" validate:"checkyesornoorunset"`
OwnerID string `json:"ownerid,omitempty"`
IsFailOver bool `json:"is_fail_over"`
IsAutoRelay bool `json:"is_auto_relay"`
//AutoRelayedPeers map[string]struct{} `json:"auto_relayed_peers"`
AutoRelayedPeers map[string]string `json:"auto_relayed_peers_v1"`
//AutoRelayedBy uuid.UUID `json:"auto_relayed_by"`
FailOverPeers map[string]struct{} `json:"fail_over_peers"`
FailedOverBy uuid.UUID `json:"failed_over_by"`
IsInternetGateway bool `json:"isinternetgateway"`
@@ -446,10 +447,10 @@ func (newNode *Node) Fill(
if newNode.ExpirationDateTime.IsZero() {
newNode.ExpirationDateTime = currentNode.ExpirationDateTime
}
if newNode.LastPeerUpdate.IsZero() {
if newNode.LastPeerUpdate.IsZero() || currentNode.LastPeerUpdate.After(newNode.LastPeerUpdate) {
newNode.LastPeerUpdate = currentNode.LastPeerUpdate
}
if newNode.LastCheckIn.IsZero() {
if newNode.LastCheckIn.IsZero() || currentNode.LastCheckIn.After(newNode.LastCheckIn) {
newNode.LastCheckIn = currentNode.LastCheckIn
}
if newNode.Network == "" {

View File

@@ -7,7 +7,6 @@ import (
"fmt"
"net/http"
"github.com/google/uuid"
"github.com/gorilla/mux"
controller "github.com/gravitl/netmaker/controllers"
"github.com/gravitl/netmaker/db"
@@ -125,12 +124,11 @@ func resetAutoRelayGw(w http.ResponseWriter, r *http.Request) {
return
}
for _, node := range nodes {
if node.AutoRelayedBy != uuid.Nil {
node.AutoRelayedBy = uuid.Nil
if len(node.AutoRelayedPeers) > 0 {
if node.Mutex != nil {
node.Mutex.Lock()
}
node.AutoRelayedPeers = make(map[string]struct{})
node.AutoRelayedPeers = make(map[string]string)
if node.Mutex != nil {
node.Mutex.Unlock()
}
@@ -374,20 +372,50 @@ func autoRelayMEUpdate(w http.ResponseWriter, r *http.Request) {
return
}
if autoRelayReq.AutoRelayGwID == "" {
// unset current gw
if node.RelayedBy != "" {
// unset relayed node from the curr relay
currRelayNode, err := logic.GetNodeByID(node.RelayedBy)
if err == nil {
newRelayedNodes := logic.RemoveAllFromSlice(currRelayNode.RelayedNodes, node.ID.String())
logic.UpdateRelayNodes(currRelayNode.ID.String(), currRelayNode.RelayedNodes, newRelayedNodes)
if node.AutoAssignGateway {
// unset current gw
if node.RelayedBy != "" {
// unset relayed node from the curr relay
currRelayNode, err := logic.GetNodeByID(node.RelayedBy)
if err == nil {
if currRelayNode.Mutex != nil {
currRelayNode.Mutex.Lock()
}
newRelayedNodes := logic.RemoveAllFromSlice(currRelayNode.RelayedNodes, node.ID.String())
currRelayNode.RelayedNodes = newRelayedNodes
logic.UpsertNode(&currRelayNode)
node.RelayedBy = ""
node.IsRelayed = false
logic.UpsertNode(&node)
if currRelayNode.Mutex != nil {
currRelayNode.Mutex.Unlock()
}
}
}
} else {
peerNode, err := logic.GetNodeByID(autoRelayReq.NodeID)
if err != nil {
slog.Error("peer not found: ", "nodeid", autoRelayReq.NodeID, "error", err)
logic.ReturnErrorResponse(
w,
r,
logic.FormatError(errors.New("peer not found"), "badrequest"),
)
return
}
delete(node.AutoRelayedPeers, peerNode.ID.String())
delete(peerNode.AutoRelayedPeers, node.ID.String())
logic.UpsertNode(&node)
logic.UpsertNode(&peerNode)
}
allNodes, err := logic.GetAllNodes()
if err == nil {
mq.PublishSingleHostPeerUpdate(host, allNodes, nil, nil, false, nil)
}
go mq.PublishPeerUpdate(false)
if node.AutoAssignGateway {
mq.HostUpdate(&models.HostUpdate{Action: models.CheckAutoAssignGw, Host: *host, Node: node})
}
logic.ReturnSuccessResponse(w, r, "unrelayed successfully")
return
}
@@ -433,7 +461,17 @@ func autoRelayMEUpdate(w http.ResponseWriter, r *http.Request) {
logic.ReturnSuccessResponse(w, r, "relayed successfully")
return
}
if node.AutoRelayedBy == uuid.Nil {
peerNode, err := logic.GetNodeByID(autoRelayReq.NodeID)
if err != nil {
slog.Error("peer not found: ", "nodeid", autoRelayReq.NodeID, "error", err)
logic.ReturnErrorResponse(
w,
r,
logic.FormatError(errors.New("peer not found"), "badrequest"),
)
return
}
if len(node.AutoRelayedPeers) == 0 {
logic.ReturnErrorResponse(w, r, logic.FormatError(errors.New("node is not auto relayed"), "badrequest"))
return
}
@@ -442,11 +480,12 @@ func autoRelayMEUpdate(w http.ResponseWriter, r *http.Request) {
logic.ReturnErrorResponse(w, r, logic.FormatError(errors.New("requested node is not a auto relay node"), "badrequest"))
return
}
if node.AutoRelayedBy == autoRelayNode.ID {
if node.AutoRelayedPeers[peerNode.ID.String()] == peerNode.AutoRelayedPeers[node.ID.String()] {
logic.ReturnErrorResponse(w, r, logic.FormatError(errors.New("already using requested relay node"), "badrequest"))
return
}
node.AutoRelayedBy = autoRelayNode.ID
node.AutoRelayedPeers[peerNode.ID.String()] = autoRelayReq.AutoRelayGwID
peerNode.AutoRelayedPeers[node.ID.String()] = autoRelayReq.AutoRelayGwID
logic.UpsertNode(&node)
slog.Info(
"[auto-relay] created relay on node",

View File

@@ -6,7 +6,6 @@ import (
"net"
"sync"
"github.com/google/uuid"
"github.com/gravitl/netmaker/db"
"github.com/gravitl/netmaker/logger"
"github.com/gravitl/netmaker/logic"
@@ -50,19 +49,18 @@ func CheckAutoRelayCtx(autoRelayNode, victimNode, peerNode models.Node) error {
if peerNode.Mutex != nil {
peerNode.Mutex.Lock()
}
_, peerHasAutoRelayed := peerNode.AutoRelayedPeers[victimNode.ID.String()]
autoRelayNodeIDPeerNode, peerHasAutoRelayed := peerNode.AutoRelayedPeers[victimNode.ID.String()]
if peerNode.Mutex != nil {
peerNode.Mutex.Unlock()
}
if victimNode.Mutex != nil {
victimNode.Mutex.Lock()
}
_, victimHasAutoRelayed := victimNode.AutoRelayedPeers[peerNode.ID.String()]
autoRelayNodeIDVictim, victimHasAutoRelayed := victimNode.AutoRelayedPeers[peerNode.ID.String()]
if victimNode.Mutex != nil {
victimNode.Mutex.Unlock()
}
if peerHasAutoRelayed && victimHasAutoRelayed &&
victimNode.AutoRelayedBy == autoRelayNode.ID && peerNode.AutoRelayedBy == autoRelayNode.ID {
if peerHasAutoRelayed && victimHasAutoRelayed && autoRelayNodeIDVictim == autoRelayNodeIDPeerNode {
return errors.New("auto relay ctx is already set")
}
return nil
@@ -71,45 +69,42 @@ func SetAutoRelayCtx(autoRelayNode, victimNode, peerNode models.Node) error {
autoRelayCtxMutex.Lock()
defer autoRelayCtxMutex.Unlock()
if peerNode.AutoRelayedPeers == nil {
peerNode.AutoRelayedPeers = make(map[string]struct{})
peerNode.AutoRelayedPeers = make(map[string]string)
}
if victimNode.AutoRelayedPeers == nil {
victimNode.AutoRelayedPeers = make(map[string]struct{})
victimNode.AutoRelayedPeers = make(map[string]string)
}
if peerNode.Mutex != nil {
peerNode.Mutex.Lock()
}
_, peerHasAutoRelayed := peerNode.AutoRelayedPeers[victimNode.ID.String()]
autoRelayNodeIDPeerNode, peerHasAutoRelayed := peerNode.AutoRelayedPeers[victimNode.ID.String()]
if peerNode.Mutex != nil {
peerNode.Mutex.Unlock()
}
if victimNode.Mutex != nil {
victimNode.Mutex.Lock()
}
_, victimHasAutoRelayed := victimNode.AutoRelayedPeers[peerNode.ID.String()]
autoRelayNodeIDVictim, victimHasAutoRelayed := victimNode.AutoRelayedPeers[peerNode.ID.String()]
if victimNode.Mutex != nil {
victimNode.Mutex.Unlock()
}
if peerHasAutoRelayed && victimHasAutoRelayed &&
victimNode.AutoRelayedBy == autoRelayNode.ID && peerNode.AutoRelayedBy == autoRelayNode.ID {
if peerHasAutoRelayed && victimHasAutoRelayed && autoRelayNodeIDVictim == autoRelayNodeIDPeerNode {
return errors.New("auto relay ctx is already set")
}
if peerNode.Mutex != nil {
peerNode.Mutex.Lock()
}
peerNode.AutoRelayedPeers[victimNode.ID.String()] = struct{}{}
peerNode.AutoRelayedPeers[victimNode.ID.String()] = autoRelayNode.ID.String()
if peerNode.Mutex != nil {
peerNode.Mutex.Unlock()
}
if victimNode.Mutex != nil {
victimNode.Mutex.Lock()
}
victimNode.AutoRelayedPeers[peerNode.ID.String()] = struct{}{}
victimNode.AutoRelayedPeers[peerNode.ID.String()] = autoRelayNode.ID.String()
if victimNode.Mutex != nil {
victimNode.Mutex.Unlock()
}
victimNode.AutoRelayedBy = autoRelayNode.ID
// peerNode.AutoRelayedBy = autoRelayNode.ID
if err := logic.UpsertNode(&victimNode); err != nil {
return err
}
@@ -172,8 +167,7 @@ func ResetAutoRelayedPeer(autoRelayedNode *models.Node) error {
if err != nil {
return err
}
autoRelayedNode.AutoRelayedBy = uuid.Nil
autoRelayedNode.AutoRelayedPeers = make(map[string]struct{})
autoRelayedNode.AutoRelayedPeers = make(map[string]string)
err = logic.UpsertNode(autoRelayedNode)
if err != nil {
return err
@@ -196,18 +190,16 @@ func ResetAutoRelay(autoRelayNode *models.Node) error {
return err
}
for _, node := range nodes {
if node.AutoRelayedBy == autoRelayNode.ID {
node.AutoRelayedBy = uuid.Nil
node.AutoRelayedPeers = make(map[string]struct{})
for autoRelayedPeerID, autoRelayID := range node.AutoRelayedPeers {
if autoRelayID != autoRelayNode.ID.String() {
continue
}
delete(node.AutoRelayedPeers, autoRelayedPeerID)
logic.UpsertNode(&node)
for _, peer := range nodes {
if peer.ID == node.ID {
continue
}
if _, ok := peer.AutoRelayedPeers[node.ID.String()]; ok {
delete(peer.AutoRelayedPeers, node.ID.String())
logic.UpsertNode(&peer)
}
peer, err := logic.GetNodeByID(autoRelayedPeerID)
if err == nil {
delete(peer.AutoRelayedPeers, node.ID.String())
logic.UpsertNode(&peer)
}
}
}
@@ -219,9 +211,12 @@ func GetAutoRelayPeerIps(peer, node *models.Node) []net.IPNet {
allowedips := []net.IPNet{}
eli, _ := (&schema.Egress{Network: node.Network}).ListByNetwork(db.WithContext(context.TODO()))
acls, _ := logic.ListAclsByNetwork(models.NetworkID(node.Network))
for autoRelayedpeerID := range node.AutoRelayedPeers {
for autoRelayedpeerID, autoRelayID := range node.AutoRelayedPeers {
if peer.ID.String() != autoRelayID {
continue
}
autoRelayedpeer, err := logic.GetNodeByID(autoRelayedpeerID)
if err == nil && (autoRelayedpeer.AutoRelayedBy == peer.ID || node.AutoRelayedBy == peer.ID) {
if err == nil {
logic.GetNodeEgressInfo(&autoRelayedpeer, eli, acls)
if autoRelayedpeer.Address.IP != nil {
allowed := net.IPNet{

View File

@@ -275,6 +275,20 @@ func MigrateToGws() {
delete(node.Tags, models.TagID(fmt.Sprintf("%s.%s", node.Network, models.OldRemoteAccessTagName)))
logic.UpsertNode(&node)
}
// deprecate failover and initialise auto relay fields
if node.IsFailOver {
node.IsFailOver = false
node.FailOverPeers = make(map[string]struct{})
node.FailedOverBy = uuid.Nil
node.AutoRelayedPeers = make(map[string]string)
logic.UpsertNode(&node)
}
if node.FailedOverBy != uuid.Nil || len(node.FailOverPeers) > 0 {
node.FailOverPeers = make(map[string]struct{})
node.FailedOverBy = uuid.Nil
node.AutoRelayedPeers = make(map[string]string)
logic.UpsertNode(&node)
}
if node.IsInternetGateway && len(node.InetNodeReq.InetNodeClientIDs) > 0 {
node.RelayedNodes = append(node.RelayedNodes, node.InetNodeReq.InetNodeClientIDs...)
node.RelayedNodes = logic.UniqueStrings(node.RelayedNodes)