auto_relay.go 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297
  1. package logic
  2. import (
  3. "context"
  4. "errors"
  5. "net"
  6. "sync"
  7. "github.com/gravitl/netmaker/db"
  8. "github.com/gravitl/netmaker/logger"
  9. "github.com/gravitl/netmaker/logic"
  10. "github.com/gravitl/netmaker/models"
  11. "github.com/gravitl/netmaker/schema"
  12. "github.com/gravitl/netmaker/servercfg"
  13. "golang.org/x/exp/slog"
  14. )
  15. var autoRelayCtxMutex = &sync.RWMutex{}
  16. var autoRelayCacheMutex = &sync.RWMutex{}
  17. var autoRelayCache = make(map[models.NetworkID][]string)
  18. func InitAutoRelayCache() {
  19. autoRelayCacheMutex.Lock()
  20. defer autoRelayCacheMutex.Unlock()
  21. allNodes, err := logic.GetAllNodes()
  22. if err != nil {
  23. return
  24. }
  25. for _, node := range allNodes {
  26. if node.IsAutoRelay {
  27. autoRelayCache[models.NetworkID(node.Network)] = append(autoRelayCache[models.NetworkID(node.Network)], node.ID.String())
  28. }
  29. }
  30. }
  31. func SetAutoRelay(node *models.Node) {
  32. node.IsAutoRelay = true
  33. }
  34. func CheckAutoRelayCtx(autoRelayNode, victimNode, peerNode models.Node) error {
  35. autoRelayCtxMutex.RLock()
  36. defer autoRelayCtxMutex.RUnlock()
  37. if peerNode.AutoRelayedPeers == nil {
  38. return nil
  39. }
  40. if victimNode.AutoRelayedPeers == nil {
  41. return nil
  42. }
  43. if peerNode.Mutex != nil {
  44. peerNode.Mutex.Lock()
  45. }
  46. autoRelayNodeIDPeerNode, peerHasAutoRelayed := peerNode.AutoRelayedPeers[victimNode.ID.String()]
  47. if peerNode.Mutex != nil {
  48. peerNode.Mutex.Unlock()
  49. }
  50. if victimNode.Mutex != nil {
  51. victimNode.Mutex.Lock()
  52. }
  53. autoRelayNodeIDVictim, victimHasAutoRelayed := victimNode.AutoRelayedPeers[peerNode.ID.String()]
  54. if victimNode.Mutex != nil {
  55. victimNode.Mutex.Unlock()
  56. }
  57. if peerHasAutoRelayed && victimHasAutoRelayed && autoRelayNodeIDVictim == autoRelayNodeIDPeerNode {
  58. return errors.New("auto relay ctx is already set")
  59. }
  60. return nil
  61. }
  62. func SetAutoRelayCtx(autoRelayNode, victimNode, peerNode models.Node) error {
  63. autoRelayCtxMutex.Lock()
  64. defer autoRelayCtxMutex.Unlock()
  65. if peerNode.AutoRelayedPeers == nil {
  66. peerNode.AutoRelayedPeers = make(map[string]string)
  67. }
  68. if victimNode.AutoRelayedPeers == nil {
  69. victimNode.AutoRelayedPeers = make(map[string]string)
  70. }
  71. if peerNode.Mutex != nil {
  72. peerNode.Mutex.Lock()
  73. }
  74. autoRelayNodeIDPeerNode, peerHasAutoRelayed := peerNode.AutoRelayedPeers[victimNode.ID.String()]
  75. if peerNode.Mutex != nil {
  76. peerNode.Mutex.Unlock()
  77. }
  78. if victimNode.Mutex != nil {
  79. victimNode.Mutex.Lock()
  80. }
  81. autoRelayNodeIDVictim, victimHasAutoRelayed := victimNode.AutoRelayedPeers[peerNode.ID.String()]
  82. if victimNode.Mutex != nil {
  83. victimNode.Mutex.Unlock()
  84. }
  85. if peerHasAutoRelayed && victimHasAutoRelayed && autoRelayNodeIDVictim == autoRelayNodeIDPeerNode {
  86. return errors.New("auto relay ctx is already set")
  87. }
  88. if peerNode.Mutex != nil {
  89. peerNode.Mutex.Lock()
  90. }
  91. peerNode.AutoRelayedPeers[victimNode.ID.String()] = autoRelayNode.ID.String()
  92. if peerNode.Mutex != nil {
  93. peerNode.Mutex.Unlock()
  94. }
  95. if victimNode.Mutex != nil {
  96. victimNode.Mutex.Lock()
  97. }
  98. victimNode.AutoRelayedPeers[peerNode.ID.String()] = autoRelayNode.ID.String()
  99. if victimNode.Mutex != nil {
  100. victimNode.Mutex.Unlock()
  101. }
  102. if err := logic.UpsertNode(&victimNode); err != nil {
  103. return err
  104. }
  105. if err := logic.UpsertNode(&peerNode); err != nil {
  106. return err
  107. }
  108. return nil
  109. }
  110. // GetAutoRelayNode - gets the host acting as autoRelay
  111. func GetAutoRelayNode(network string, allNodes []models.Node) (models.Node, error) {
  112. nodes := logic.GetNetworkNodesMemory(allNodes, network)
  113. for _, node := range nodes {
  114. if node.IsAutoRelay {
  115. return node, nil
  116. }
  117. }
  118. return models.Node{}, errors.New("auto relay not found")
  119. }
  120. func RemoveAutoRelayFromCache(network string) {
  121. autoRelayCacheMutex.Lock()
  122. defer autoRelayCacheMutex.Unlock()
  123. delete(autoRelayCache, models.NetworkID(network))
  124. }
  125. func SetAutoRelayInCache(node models.Node) {
  126. autoRelayCacheMutex.Lock()
  127. defer autoRelayCacheMutex.Unlock()
  128. autoRelayCache[models.NetworkID(node.Network)] = append(autoRelayCache[models.NetworkID(node.Network)], node.ID.String())
  129. }
  130. // DoesAutoRelayExist - checks if autorelay exists already in the network
  131. func DoesAutoRelayExist(network string) (autoRelayNodes []models.Node) {
  132. autoRelayCacheMutex.RLock()
  133. defer autoRelayCacheMutex.RUnlock()
  134. if !servercfg.CacheEnabled() {
  135. nodes, _ := logic.GetNetworkNodes(network)
  136. for _, node := range nodes {
  137. if node.IsAutoRelay {
  138. autoRelayNodes = append(autoRelayNodes, node)
  139. }
  140. }
  141. }
  142. if nodeIDs, ok := autoRelayCache[models.NetworkID(network)]; ok {
  143. for _, nodeID := range nodeIDs {
  144. autoRelayNode, err := logic.GetNodeByID(nodeID)
  145. if err == nil {
  146. autoRelayNodes = append(autoRelayNodes, autoRelayNode)
  147. }
  148. }
  149. }
  150. return
  151. }
  152. // ResetAutoRelayedPeer - removes auto relayed over node from network peers
  153. func ResetAutoRelayedPeer(autoRelayedNode *models.Node) error {
  154. nodes, err := logic.GetNetworkNodes(autoRelayedNode.Network)
  155. if err != nil {
  156. return err
  157. }
  158. autoRelayedNode.AutoRelayedPeers = make(map[string]string)
  159. err = logic.UpsertNode(autoRelayedNode)
  160. if err != nil {
  161. return err
  162. }
  163. for _, node := range nodes {
  164. if node.AutoRelayedPeers == nil || node.ID == autoRelayedNode.ID {
  165. continue
  166. }
  167. delete(node.AutoRelayedPeers, autoRelayedNode.ID.String())
  168. logic.UpsertNode(&node)
  169. }
  170. return nil
  171. }
  172. // ResetAutoRelay - reset autorelayed peers
  173. func ResetAutoRelay(autoRelayNode *models.Node) error {
  174. // Unset autorelayed peers
  175. nodes, err := logic.GetNetworkNodes(autoRelayNode.Network)
  176. if err != nil {
  177. return err
  178. }
  179. for _, node := range nodes {
  180. for autoRelayedPeerID, autoRelayID := range node.AutoRelayedPeers {
  181. if autoRelayID != autoRelayNode.ID.String() {
  182. continue
  183. }
  184. delete(node.AutoRelayedPeers, autoRelayedPeerID)
  185. logic.UpsertNode(&node)
  186. peer, err := logic.GetNodeByID(autoRelayedPeerID)
  187. if err == nil {
  188. delete(peer.AutoRelayedPeers, node.ID.String())
  189. logic.UpsertNode(&peer)
  190. }
  191. }
  192. }
  193. return nil
  194. }
  195. // GetAutoRelayPeerIps - adds the autorelayed peerIps by the peer
  196. func GetAutoRelayPeerIps(peer, node *models.Node) []net.IPNet {
  197. allowedips := []net.IPNet{}
  198. eli, _ := (&schema.Egress{Network: node.Network}).ListByNetwork(db.WithContext(context.TODO()))
  199. acls, _ := logic.ListAclsByNetwork(models.NetworkID(node.Network))
  200. for autoRelayedpeerID, autoRelayID := range node.AutoRelayedPeers {
  201. if peer.ID.String() != autoRelayID {
  202. continue
  203. }
  204. autoRelayedpeer, err := logic.GetNodeByID(autoRelayedpeerID)
  205. if err == nil {
  206. logic.GetNodeEgressInfo(&autoRelayedpeer, eli, acls)
  207. if autoRelayedpeer.Address.IP != nil {
  208. allowed := net.IPNet{
  209. IP: autoRelayedpeer.Address.IP,
  210. Mask: net.CIDRMask(32, 32),
  211. }
  212. allowedips = append(allowedips, allowed)
  213. }
  214. if autoRelayedpeer.Address6.IP != nil {
  215. allowed := net.IPNet{
  216. IP: autoRelayedpeer.Address6.IP,
  217. Mask: net.CIDRMask(128, 128),
  218. }
  219. allowedips = append(allowedips, allowed)
  220. }
  221. if autoRelayedpeer.EgressDetails.IsEgressGateway {
  222. allowedips = append(allowedips, logic.GetEgressIPs(&autoRelayedpeer)...)
  223. }
  224. if autoRelayedpeer.IsRelay {
  225. for _, id := range autoRelayedpeer.RelayedNodes {
  226. rNode, _ := logic.GetNodeByID(id)
  227. logic.GetNodeEgressInfo(&rNode, eli, acls)
  228. if rNode.Address.IP != nil {
  229. allowed := net.IPNet{
  230. IP: rNode.Address.IP,
  231. Mask: net.CIDRMask(32, 32),
  232. }
  233. allowedips = append(allowedips, allowed)
  234. }
  235. if rNode.Address6.IP != nil {
  236. allowed := net.IPNet{
  237. IP: rNode.Address6.IP,
  238. Mask: net.CIDRMask(128, 128),
  239. }
  240. allowedips = append(allowedips, allowed)
  241. }
  242. if rNode.EgressDetails.IsEgressGateway {
  243. allowedips = append(allowedips, logic.GetEgressIPs(&rNode)...)
  244. }
  245. }
  246. }
  247. // handle ingress gateway peers
  248. if autoRelayedpeer.IsIngressGateway {
  249. extPeers, _, _, err := logic.GetExtPeers(&autoRelayedpeer, node)
  250. if err != nil {
  251. logger.Log(2, "could not retrieve ext peers for ", peer.ID.String(), err.Error())
  252. }
  253. for _, extPeer := range extPeers {
  254. allowedips = append(allowedips, extPeer.AllowedIPs...)
  255. }
  256. }
  257. }
  258. }
  259. return allowedips
  260. }
  261. func CreateAutoRelay(node models.Node) error {
  262. host, err := logic.GetHost(node.HostID.String())
  263. if err != nil {
  264. return err
  265. }
  266. if host.OS != models.OS_Types.Linux {
  267. return errors.New("only linux nodes are allowed to be set as autoRelay")
  268. }
  269. if node.IsRelayed {
  270. return errors.New("relayed node cannot be set as autoRelay")
  271. }
  272. node.IsAutoRelay = true
  273. err = logic.UpsertNode(&node)
  274. if err != nil {
  275. slog.Error("failed to upsert node", "node", node.ID.String(), "error", err)
  276. return err
  277. }
  278. if servercfg.CacheEnabled() {
  279. SetAutoRelayInCache(node)
  280. }
  281. return nil
  282. }