auto_relay.go 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660
  1. package controllers
  2. import (
  3. "context"
  4. "encoding/json"
  5. "errors"
  6. "fmt"
  7. "net/http"
  8. "github.com/gorilla/mux"
  9. controller "github.com/gravitl/netmaker/controllers"
  10. "github.com/gravitl/netmaker/db"
  11. "github.com/gravitl/netmaker/logger"
  12. "github.com/gravitl/netmaker/logic"
  13. "github.com/gravitl/netmaker/models"
  14. "github.com/gravitl/netmaker/mq"
  15. proLogic "github.com/gravitl/netmaker/pro/logic"
  16. "github.com/gravitl/netmaker/schema"
  17. "github.com/gravitl/netmaker/servercfg"
  18. "golang.org/x/exp/slog"
  19. )
  20. // AutoRelayHandlers - handlers for AutoRelay
  21. func AutoRelayHandlers(r *mux.Router) {
  22. r.HandleFunc("/api/v1/node/{nodeid}/auto_relay", controller.Authorize(true, false, "host", http.HandlerFunc(getAutoRelayGws))).
  23. Methods(http.MethodGet)
  24. r.HandleFunc("/api/v1/node/{nodeid}/auto_relay", logic.SecurityCheck(true, http.HandlerFunc(setAutoRelay))).
  25. Methods(http.MethodPost)
  26. r.HandleFunc("/api/v1/node/{nodeid}/auto_relay", logic.SecurityCheck(true, http.HandlerFunc(unsetAutoRelay))).
  27. Methods(http.MethodDelete)
  28. r.HandleFunc("/api/v1/node/{network}/auto_relay/reset", logic.SecurityCheck(true, http.HandlerFunc(resetAutoRelayGw))).
  29. Methods(http.MethodPost)
  30. r.HandleFunc("/api/v1/node/{nodeid}/auto_relay_me", controller.Authorize(true, false, "host", http.HandlerFunc(autoRelayME))).
  31. Methods(http.MethodPost)
  32. r.HandleFunc("/api/v1/node/{nodeid}/auto_relay_me", controller.Authorize(true, false, "host", http.HandlerFunc(autoRelayMEUpdate))).
  33. Methods(http.MethodPut)
  34. r.HandleFunc("/api/v1/node/{nodeid}/auto_relay_check", controller.Authorize(true, false, "host", http.HandlerFunc(checkautoRelayCtx))).
  35. Methods(http.MethodGet)
  36. }
  37. // @Summary Get auto relay nodes
  38. // @Router /api/v1/node/{nodeid}/auto_relay [get]
  39. // @Tags PRO
  40. // @Param nodeid path string true "Node ID"
  41. // @Success 200 {object} models.Node
  42. // @Failure 400 {object} models.ErrorResponse
  43. // @Failure 404 {object} models.ErrorResponse
  44. func getAutoRelayGws(w http.ResponseWriter, r *http.Request) {
  45. var params = mux.Vars(r)
  46. nodeid := params["nodeid"]
  47. // confirm host exists
  48. node, err := logic.GetNodeByID(nodeid)
  49. if err != nil {
  50. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
  51. return
  52. }
  53. autoRelayNodes := proLogic.DoesAutoRelayExist(node.Network)
  54. if len(autoRelayNodes) == 0 {
  55. logic.ReturnErrorResponse(
  56. w,
  57. r,
  58. logic.FormatError(errors.New("autorelay node not found"), "notfound"),
  59. )
  60. return
  61. }
  62. defaultPolicy, err := logic.GetDefaultPolicy(models.NetworkID(node.Network), models.DevicePolicy)
  63. if err != nil {
  64. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
  65. return
  66. }
  67. returnautoRelayNodes := []models.Node{}
  68. if !defaultPolicy.Enabled {
  69. for _, autoRelayNode := range autoRelayNodes {
  70. if logic.IsPeerAllowed(node, autoRelayNode, false) {
  71. returnautoRelayNodes = append(returnautoRelayNodes, autoRelayNode)
  72. }
  73. }
  74. } else {
  75. returnautoRelayNodes = autoRelayNodes
  76. }
  77. w.Header().Set("Content-Type", "application/json")
  78. logic.ReturnSuccessResponseWithJson(w, r, returnautoRelayNodes, "get autorelay node successfully")
  79. }
  80. // @Summary Create AutoRelay node
  81. // @Router /api/v1/node/{nodeid}/auto_relay [post]
  82. // @Tags PRO
  83. // @Param nodeid path string true "Node ID"
  84. // @Success 200 {object} models.Node
  85. // @Failure 400 {object} models.ErrorResponse
  86. // @Failure 500 {object} models.ErrorResponse
  87. func setAutoRelay(w http.ResponseWriter, r *http.Request) {
  88. var params = mux.Vars(r)
  89. nodeid := params["nodeid"]
  90. // confirm host exists
  91. node, err := logic.GetNodeByID(nodeid)
  92. if err != nil {
  93. slog.Error("failed to get node:", "error", err.Error())
  94. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
  95. return
  96. }
  97. err = proLogic.CreateAutoRelay(node)
  98. if err != nil {
  99. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
  100. return
  101. }
  102. go mq.PublishPeerUpdate(false)
  103. w.Header().Set("Content-Type", "application/json")
  104. logic.ReturnSuccessResponseWithJson(w, r, node, "created autorelay successfully")
  105. }
  106. // @Summary Reset AutoRelay for a network
  107. // @Router /api/v1/node/{network}/auto_relay/reset [post]
  108. // @Tags PRO
  109. // @Param network path string true "Network ID"
  110. // @Success 200 {object} models.SuccessResponse
  111. // @Failure 500 {object} models.ErrorResponse
  112. func resetAutoRelayGw(w http.ResponseWriter, r *http.Request) {
  113. var params = mux.Vars(r)
  114. net := params["network"]
  115. nodes, err := logic.GetNetworkNodes(net)
  116. if err != nil {
  117. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
  118. return
  119. }
  120. for _, node := range nodes {
  121. if len(node.AutoRelayedPeers) > 0 {
  122. if node.Mutex != nil {
  123. node.Mutex.Lock()
  124. }
  125. node.AutoRelayedPeers = make(map[string]string)
  126. if node.Mutex != nil {
  127. node.Mutex.Unlock()
  128. }
  129. logic.UpsertNode(&node)
  130. }
  131. }
  132. go mq.PublishPeerUpdate(false)
  133. w.Header().Set("Content-Type", "application/json")
  134. logic.ReturnSuccessResponse(w, r, "autorelay has been reset successfully")
  135. }
  136. // @Summary Delete autorelay node
  137. // @Router /api/v1/node/{nodeid}/auto_relay [delete]
  138. // @Tags PRO
  139. // @Param nodeid path string true "Node ID"
  140. // @Success 200 {object} models.Node
  141. // @Failure 400 {object} models.ErrorResponse
  142. // @Failure 500 {object} models.ErrorResponse
  143. func unsetAutoRelay(w http.ResponseWriter, r *http.Request) {
  144. var params = mux.Vars(r)
  145. nodeid := params["nodeid"]
  146. // confirm host exists
  147. node, err := logic.GetNodeByID(nodeid)
  148. if err != nil {
  149. slog.Error("failed to get node:", "error", err.Error())
  150. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
  151. return
  152. }
  153. node.IsAutoRelay = false
  154. // Reset AutoRelayed Peers
  155. err = logic.UpsertNode(&node)
  156. if err != nil {
  157. slog.Error("failed to upsert node", "node", node.ID.String(), "error", err)
  158. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
  159. return
  160. }
  161. if servercfg.CacheEnabled() {
  162. proLogic.RemoveAutoRelayFromCache(node.Network)
  163. }
  164. go func() {
  165. proLogic.ResetAutoRelay(&node)
  166. mq.PublishPeerUpdate(false)
  167. }()
  168. w.Header().Set("Content-Type", "application/json")
  169. logic.ReturnSuccessResponseWithJson(w, r, node, "deleted autorelay successfully")
  170. }
  171. // @Summary AutoRelay me
  172. // @Router /api/v1/node/{nodeid}/auto_relay_me [post]
  173. // @Tags PRO
  174. // @Param nodeid path string true "Node ID"
  175. // @Accept json
  176. // @Param body body models.AutoRelayMeReq true "AutoRelay request"
  177. // @Success 200 {object} models.SuccessResponse
  178. // @Failure 400 {object} models.ErrorResponse
  179. // @Failure 500 {object} models.ErrorResponse
  180. func autoRelayME(w http.ResponseWriter, r *http.Request) {
  181. var params = mux.Vars(r)
  182. nodeid := params["nodeid"]
  183. // confirm host exists
  184. node, err := logic.GetNodeByID(nodeid)
  185. if err != nil {
  186. logger.Log(0, r.Header.Get("user"), "failed to get node:", err.Error())
  187. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
  188. return
  189. }
  190. host, err := logic.GetHost(node.HostID.String())
  191. if err != nil {
  192. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
  193. return
  194. }
  195. var autoRelayReq models.AutoRelayMeReq
  196. err = json.NewDecoder(r.Body).Decode(&autoRelayReq)
  197. if err != nil {
  198. logger.Log(0, r.Header.Get("user"), "error decoding request body: ", err.Error())
  199. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
  200. return
  201. }
  202. autoRelayNode, err := logic.GetNodeByID(autoRelayReq.AutoRelayGwID)
  203. if err != nil {
  204. logic.ReturnErrorResponse(
  205. w,
  206. r,
  207. logic.FormatError(
  208. fmt.Errorf("req-from: %s, autorelay node doesn't exist in the network", host.Name),
  209. "badrequest",
  210. ),
  211. )
  212. return
  213. }
  214. var sendPeerUpdate bool
  215. peerNode, err := logic.GetNodeByID(autoRelayReq.NodeID)
  216. if err != nil {
  217. slog.Error("peer not found: ", "nodeid", autoRelayReq.NodeID, "error", err)
  218. logic.ReturnErrorResponse(
  219. w,
  220. r,
  221. logic.FormatError(errors.New("peer not found"), "badrequest"),
  222. )
  223. return
  224. }
  225. eli, _ := (&schema.Egress{Network: node.Network}).ListByNetwork(db.WithContext(context.TODO()))
  226. acls, _ := logic.ListAclsByNetwork(models.NetworkID(node.Network))
  227. logic.GetNodeEgressInfo(&node, eli, acls)
  228. logic.GetNodeEgressInfo(&peerNode, eli, acls)
  229. logic.GetNodeEgressInfo(&autoRelayNode, eli, acls)
  230. if peerNode.IsAutoRelay {
  231. logic.ReturnErrorResponse(
  232. w,
  233. r,
  234. logic.FormatError(errors.New("peer is acting as autorelay"), "badrequest"),
  235. )
  236. return
  237. }
  238. if node.IsAutoRelay {
  239. logic.ReturnErrorResponse(
  240. w,
  241. r,
  242. logic.FormatError(errors.New("node is acting as autorelay"), "badrequest"),
  243. )
  244. return
  245. }
  246. if peerNode.IsAutoRelay {
  247. logic.ReturnErrorResponse(
  248. w,
  249. r,
  250. logic.FormatError(errors.New("peer is acting as autorelay"), "badrequest"),
  251. )
  252. return
  253. }
  254. if node.IsRelayed && node.RelayedBy == peerNode.ID.String() {
  255. logic.ReturnErrorResponse(
  256. w,
  257. r,
  258. logic.FormatError(errors.New("node is relayed by peer node"), "badrequest"),
  259. )
  260. return
  261. }
  262. if node.IsRelay && peerNode.RelayedBy == node.ID.String() {
  263. logic.ReturnErrorResponse(
  264. w,
  265. r,
  266. logic.FormatError(errors.New("node acting as relay for the peer node"), "badrequest"),
  267. )
  268. return
  269. }
  270. if (node.InternetGwID != "" && autoRelayNode.IsInternetGateway && node.InternetGwID != autoRelayNode.ID.String()) ||
  271. (peerNode.InternetGwID != "" && autoRelayNode.IsInternetGateway && peerNode.InternetGwID != autoRelayNode.ID.String()) {
  272. logic.ReturnErrorResponse(
  273. w,
  274. r,
  275. logic.FormatError(
  276. errors.New("node using a internet gw by the peer node"),
  277. "badrequest",
  278. ),
  279. )
  280. return
  281. }
  282. if node.IsInternetGateway && peerNode.InternetGwID == node.ID.String() {
  283. logic.ReturnErrorResponse(
  284. w,
  285. r,
  286. logic.FormatError(
  287. errors.New("node acting as internet gw for the peer node"),
  288. "badrequest",
  289. ),
  290. )
  291. return
  292. }
  293. if node.InternetGwID != "" && node.InternetGwID == peerNode.ID.String() {
  294. logic.ReturnErrorResponse(
  295. w,
  296. r,
  297. logic.FormatError(
  298. errors.New("node using a internet gw by the peer node"),
  299. "badrequest",
  300. ),
  301. )
  302. return
  303. }
  304. err = proLogic.SetAutoRelayCtx(autoRelayNode, node, peerNode)
  305. if err != nil {
  306. slog.Debug("failed to create autorelay", "id", node.ID.String(),
  307. "network", node.Network, "error", err)
  308. logic.ReturnErrorResponse(
  309. w,
  310. r,
  311. logic.FormatError(fmt.Errorf("failed to create autorelay: %v", err), "internal"),
  312. )
  313. return
  314. }
  315. slog.Info(
  316. "[auto-relay] created relay on node",
  317. "node",
  318. node.ID.String(),
  319. "network",
  320. node.Network,
  321. )
  322. sendPeerUpdate = true
  323. if sendPeerUpdate {
  324. go mq.PublishPeerUpdate(false)
  325. }
  326. w.Header().Set("Content-Type", "application/json")
  327. logic.ReturnSuccessResponse(w, r, "relayed successfully")
  328. }
  329. // @Summary AutoRelay me
  330. // @Router /api/v1/node/{nodeid}/auto_relay_me [put]
  331. // @Tags PRO
  332. // @Param nodeid path string true "Node ID"
  333. // @Accept json
  334. // @Param body body models.AutoRelayMeReq true "AutoRelay request"
  335. // @Success 200 {object} models.SuccessResponse
  336. // @Failure 400 {object} models.ErrorResponse
  337. // @Failure 500 {object} models.ErrorResponse
  338. func autoRelayMEUpdate(w http.ResponseWriter, r *http.Request) {
  339. var params = mux.Vars(r)
  340. nodeid := params["nodeid"]
  341. // confirm host exists
  342. node, err := logic.GetNodeByID(nodeid)
  343. if err != nil {
  344. logger.Log(0, r.Header.Get("user"), "failed to get node:", err.Error())
  345. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
  346. return
  347. }
  348. host, err := logic.GetHost(node.HostID.String())
  349. if err != nil {
  350. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
  351. return
  352. }
  353. var autoRelayReq models.AutoRelayMeReq
  354. err = json.NewDecoder(r.Body).Decode(&autoRelayReq)
  355. if err != nil {
  356. logger.Log(0, r.Header.Get("user"), "error decoding request body: ", err.Error())
  357. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
  358. return
  359. }
  360. if autoRelayReq.AutoRelayGwID == "" {
  361. if node.AutoAssignGateway {
  362. // unset current gw
  363. if node.RelayedBy != "" {
  364. // unset relayed node from the curr relay
  365. currRelayNode, err := logic.GetNodeByID(node.RelayedBy)
  366. if err == nil {
  367. if currRelayNode.Mutex != nil {
  368. currRelayNode.Mutex.Lock()
  369. }
  370. newRelayedNodes := logic.RemoveAllFromSlice(currRelayNode.RelayedNodes, node.ID.String())
  371. currRelayNode.RelayedNodes = newRelayedNodes
  372. logic.UpsertNode(&currRelayNode)
  373. node.RelayedBy = ""
  374. node.IsRelayed = false
  375. logic.UpsertNode(&node)
  376. if currRelayNode.Mutex != nil {
  377. currRelayNode.Mutex.Unlock()
  378. }
  379. }
  380. }
  381. } else {
  382. peerNode, err := logic.GetNodeByID(autoRelayReq.NodeID)
  383. if err != nil {
  384. slog.Error("peer not found: ", "nodeid", autoRelayReq.NodeID, "error", err)
  385. logic.ReturnErrorResponse(
  386. w,
  387. r,
  388. logic.FormatError(errors.New("peer not found"), "badrequest"),
  389. )
  390. return
  391. }
  392. delete(node.AutoRelayedPeers, peerNode.ID.String())
  393. delete(peerNode.AutoRelayedPeers, node.ID.String())
  394. logic.UpsertNode(&node)
  395. logic.UpsertNode(&peerNode)
  396. }
  397. allNodes, err := logic.GetAllNodes()
  398. if err == nil {
  399. mq.PublishSingleHostPeerUpdate(host, allNodes, nil, nil, false, nil)
  400. }
  401. go mq.PublishPeerUpdate(false)
  402. if node.AutoAssignGateway {
  403. mq.HostUpdate(&models.HostUpdate{Action: models.CheckAutoAssignGw, Host: *host, Node: node})
  404. }
  405. logic.ReturnSuccessResponse(w, r, "unrelayed successfully")
  406. return
  407. }
  408. autoRelayNode, err := logic.GetNodeByID(autoRelayReq.AutoRelayGwID)
  409. if err != nil {
  410. logic.ReturnErrorResponse(
  411. w,
  412. r,
  413. logic.FormatError(
  414. fmt.Errorf("req-from: %s, autorelay node doesn't exist in the network", host.Name),
  415. "badrequest",
  416. ),
  417. )
  418. return
  419. }
  420. if !autoRelayNode.IsGw {
  421. logic.ReturnErrorResponse(
  422. w,
  423. r,
  424. logic.FormatError(
  425. fmt.Errorf(" autorelay node is not a gw"),
  426. "badrequest",
  427. ),
  428. )
  429. return
  430. }
  431. if node.AutoAssignGateway {
  432. if node.RelayedBy != autoRelayReq.AutoRelayGwID {
  433. if node.RelayedBy != "" {
  434. // unset relayed node from the curr relay
  435. currRelayNode, err := logic.GetNodeByID(node.RelayedBy)
  436. if err == nil {
  437. newRelayedNodes := logic.RemoveAllFromSlice(currRelayNode.RelayedNodes, node.ID.String())
  438. logic.UpdateRelayNodes(currRelayNode.ID.String(), currRelayNode.RelayedNodes, newRelayedNodes)
  439. }
  440. }
  441. newNodes := []string{node.ID.String()}
  442. newNodes = append(newNodes, autoRelayNode.RelayedNodes...)
  443. logic.UpdateRelayNodes(autoRelayNode.ID.String(), autoRelayNode.RelayedNodes, newNodes)
  444. go mq.PublishPeerUpdate(false)
  445. }
  446. w.Header().Set("Content-Type", "application/json")
  447. logic.ReturnSuccessResponse(w, r, "relayed successfully")
  448. return
  449. }
  450. peerNode, err := logic.GetNodeByID(autoRelayReq.NodeID)
  451. if err != nil {
  452. slog.Error("peer not found: ", "nodeid", autoRelayReq.NodeID, "error", err)
  453. logic.ReturnErrorResponse(
  454. w,
  455. r,
  456. logic.FormatError(errors.New("peer not found"), "badrequest"),
  457. )
  458. return
  459. }
  460. if len(node.AutoRelayedPeers) == 0 {
  461. logic.ReturnErrorResponse(w, r, logic.FormatError(errors.New("node is not auto relayed"), "badrequest"))
  462. return
  463. }
  464. if !autoRelayNode.IsAutoRelay {
  465. logic.ReturnErrorResponse(w, r, logic.FormatError(errors.New("requested node is not a auto relay node"), "badrequest"))
  466. return
  467. }
  468. if node.AutoRelayedPeers[peerNode.ID.String()] == peerNode.AutoRelayedPeers[node.ID.String()] {
  469. logic.ReturnErrorResponse(w, r, logic.FormatError(errors.New("already using requested relay node"), "badrequest"))
  470. return
  471. }
  472. node.AutoRelayedPeers[peerNode.ID.String()] = autoRelayReq.AutoRelayGwID
  473. peerNode.AutoRelayedPeers[node.ID.String()] = autoRelayReq.AutoRelayGwID
  474. logic.UpsertNode(&node)
  475. slog.Info(
  476. "[auto-relay] created relay on node",
  477. "node",
  478. node.ID.String(),
  479. "network",
  480. node.Network,
  481. )
  482. go mq.PublishPeerUpdate(false)
  483. w.Header().Set("Content-Type", "application/json")
  484. logic.ReturnSuccessResponse(w, r, "relayed successfully")
  485. }
  486. // @Summary checkautoRelayCtx
  487. // @Router /api/v1/node/{nodeid}/auto_relay_check [get]
  488. // @Tags PRO
  489. // @Param nodeid path string true "Node ID"
  490. // @Accept json
  491. // @Param body body models.AutoRelayMeReq true "autorelay request"
  492. // @Success 200 {object} models.SuccessResponse
  493. // @Failure 400 {object} models.ErrorResponse
  494. // @Failure 500 {object} models.ErrorResponse
  495. func checkautoRelayCtx(w http.ResponseWriter, r *http.Request) {
  496. var params = mux.Vars(r)
  497. nodeid := params["nodeid"]
  498. // confirm host exists
  499. node, err := logic.GetNodeByID(nodeid)
  500. if err != nil {
  501. logger.Log(0, r.Header.Get("user"), "failed to get node:", err.Error())
  502. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
  503. return
  504. }
  505. host, err := logic.GetHost(node.HostID.String())
  506. if err != nil {
  507. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
  508. return
  509. }
  510. var autoRelayReq models.AutoRelayMeReq
  511. err = json.NewDecoder(r.Body).Decode(&autoRelayReq)
  512. if err != nil {
  513. logger.Log(0, r.Header.Get("user"), "error decoding request body: ", err.Error())
  514. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
  515. return
  516. }
  517. autoRelayNode, err := logic.GetNodeByID(autoRelayReq.AutoRelayGwID)
  518. if err != nil {
  519. logic.ReturnErrorResponse(
  520. w,
  521. r,
  522. logic.FormatError(
  523. fmt.Errorf("req-from: %s, autorelay node doesn't exist in the network", host.Name),
  524. "badrequest",
  525. ),
  526. )
  527. return
  528. }
  529. peerNode, err := logic.GetNodeByID(autoRelayReq.NodeID)
  530. if err != nil {
  531. slog.Error("peer not found: ", "nodeid", autoRelayReq.NodeID, "error", err)
  532. logic.ReturnErrorResponse(
  533. w,
  534. r,
  535. logic.FormatError(errors.New("peer not found"), "badrequest"),
  536. )
  537. return
  538. }
  539. eli, _ := (&schema.Egress{Network: node.Network}).ListByNetwork(db.WithContext(context.TODO()))
  540. acls, _ := logic.ListAclsByNetwork(models.NetworkID(node.Network))
  541. logic.GetNodeEgressInfo(&node, eli, acls)
  542. logic.GetNodeEgressInfo(&peerNode, eli, acls)
  543. logic.GetNodeEgressInfo(&autoRelayNode, eli, acls)
  544. if peerNode.IsAutoRelay {
  545. logic.ReturnErrorResponse(
  546. w,
  547. r,
  548. logic.FormatError(errors.New("peer is acting as autorelay"), "badrequest"),
  549. )
  550. return
  551. }
  552. if node.IsAutoRelay {
  553. logic.ReturnErrorResponse(
  554. w,
  555. r,
  556. logic.FormatError(errors.New("node is acting as autorelay"), "badrequest"),
  557. )
  558. return
  559. }
  560. if peerNode.IsAutoRelay {
  561. logic.ReturnErrorResponse(
  562. w,
  563. r,
  564. logic.FormatError(errors.New("peer is acting as autorelay"), "badrequest"),
  565. )
  566. return
  567. }
  568. if node.IsRelayed && node.RelayedBy == peerNode.ID.String() {
  569. logic.ReturnErrorResponse(
  570. w,
  571. r,
  572. logic.FormatError(errors.New("node is relayed by peer node"), "badrequest"),
  573. )
  574. return
  575. }
  576. if node.IsRelay && peerNode.RelayedBy == node.ID.String() {
  577. logic.ReturnErrorResponse(
  578. w,
  579. r,
  580. logic.FormatError(errors.New("node acting as relay for the peer node"), "badrequest"),
  581. )
  582. return
  583. }
  584. if (node.InternetGwID != "" && autoRelayNode.IsInternetGateway && node.InternetGwID != autoRelayNode.ID.String()) ||
  585. (peerNode.InternetGwID != "" && autoRelayNode.IsInternetGateway && peerNode.InternetGwID != autoRelayNode.ID.String()) {
  586. logic.ReturnErrorResponse(
  587. w,
  588. r,
  589. logic.FormatError(
  590. errors.New("node using a internet gw by the peer node"),
  591. "badrequest",
  592. ),
  593. )
  594. return
  595. }
  596. if node.IsInternetGateway && peerNode.InternetGwID == node.ID.String() {
  597. logic.ReturnErrorResponse(
  598. w,
  599. r,
  600. logic.FormatError(
  601. errors.New("node acting as internet gw for the peer node"),
  602. "badrequest",
  603. ),
  604. )
  605. return
  606. }
  607. if node.InternetGwID != "" && node.InternetGwID == peerNode.ID.String() {
  608. logic.ReturnErrorResponse(
  609. w,
  610. r,
  611. logic.FormatError(
  612. errors.New("node using a internet gw by the peer node"),
  613. "badrequest",
  614. ),
  615. )
  616. return
  617. }
  618. if ok := logic.IsPeerAllowed(node, peerNode, true); !ok {
  619. logic.ReturnErrorResponse(
  620. w,
  621. r,
  622. logic.FormatError(
  623. errors.New("peers are not allowed to communicate"),
  624. "badrequest",
  625. ),
  626. )
  627. return
  628. }
  629. err = proLogic.CheckAutoRelayCtx(autoRelayNode, node, peerNode)
  630. if err != nil {
  631. slog.Error("autorelay ctx cannot be set ", "error", err)
  632. logic.ReturnErrorResponse(
  633. w,
  634. r,
  635. logic.FormatError(fmt.Errorf("autorelay ctx cannot be set: %v", err), "internal"),
  636. )
  637. return
  638. }
  639. w.Header().Set("Content-Type", "application/json")
  640. logic.ReturnSuccessResponse(w, r, "autorelay can be set")
  641. }